/* * Copyright (C) 2011 Google Inc. * Licensed to The Android Open Source Project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.yaoyumeng.v2ex.ui.fragment; import android.support.v4.app.Fragment; import android.content.Context; import android.graphics.Bitmap; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.WindowManager; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.listener.ImageLoadingProgressListener; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.assist.ImageSize; import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; import com.yaoyumeng.v2ex.R; import com.yaoyumeng.v2ex.ui.photo.ImageUtils; import com.yaoyumeng.v2ex.ui.photo.PhotoView; import com.yaoyumeng.v2ex.ui.photo.PhotoViewCallbacks; /** * Displays a photo. */ public class PhotoViewFragment extends BaseFragment implements OnClickListener, PhotoViewCallbacks.OnScreenListener { protected static ImageSize sTargetSize = new ImageSize(1024, 1024); protected static DisplayImageOptions sOptions = new DisplayImageOptions.Builder() .bitmapConfig(Bitmap.Config.RGB_565) .imageScaleType(ImageScaleType.EXACTLY) .cacheOnDisc(true) .displayer(new FadeInBitmapDisplayer(300)) .build(); public final static String ARG_POSITION = "arg-position"; public static final String ARG_PHOTO_DOWNLOAD_URL = "arg-photo-download-url"; /** * The size of the photo */ public static Integer sPhotoSize; protected PhotoView mPhotoView; protected String mDownloadUrl; protected int mPosition; protected PhotoViewCallbacks mCallback; /** * Whether or not the progress bar is showing valid information about the progress stated */ protected boolean mProgressBarNeeded = true; public static Fragment newInstance(String imageUrl, int position) { final Bundle bundle = new Bundle(); bundle.putInt(ARG_POSITION, position); bundle.putString(ARG_PHOTO_DOWNLOAD_URL, imageUrl); final PhotoViewFragment fragment = new PhotoViewFragment(); fragment.setArguments(bundle); return fragment; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mCallback = (PhotoViewCallbacks) getActivity(); if (mCallback == null) { throw new IllegalArgumentException("Activity must be a derived class of PhotoViewActivity"); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (sPhotoSize == null) { final DisplayMetrics metrics = new DisplayMetrics(); final WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE); final ImageUtils.ImageSize imageSize = ImageUtils.sUseImageSize; wm.getDefaultDisplay().getMetrics(metrics); switch (imageSize) { case EXTRA_SMALL: // Use a photo that's 80% of the "small" size sPhotoSize = (Math.min(metrics.heightPixels, metrics.widthPixels) * 800) / 1000; break; case SMALL: // Fall through. case NORMAL: // Fall through. default: sPhotoSize = Math.min(metrics.heightPixels, metrics.widthPixels); break; } } final Bundle bundle = getArguments(); if (bundle == null) { return; } mDownloadUrl = bundle.getString(ARG_PHOTO_DOWNLOAD_URL); mPosition = bundle.getInt(ARG_POSITION); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragment_photo_view, container, false); initializeView(view); return view; } protected void initializeView(View view) { mPhotoView = (PhotoView) view.findViewById(R.id.photo_view); mPhotoView.setMaxInitialScale(5); mPhotoView.setOnClickListener(this); mPhotoView.setFullScreen(false, false); mPhotoView.enableImageTransforms(false); } @Override public void onResume() { super.onResume(); mCallback.addScreenListener(mPosition, this); if (!isPhotoBound()) { mProgressBarNeeded = true; startLoadBitmapTask(); } } @Override public void onPause() { mCallback.removeScreenListener(mPosition); resetPhotoView(); super.onPause(); } @Override public void onDestroyView() { // Clean up views and other components if (mPhotoView != null) { mPhotoView.clear(); mPhotoView = null; } super.onDestroyView(); } private void startLoadBitmapTask() { ImageLoader.getInstance().loadImage(mDownloadUrl, sTargetSize, sOptions, new SimpleImageLoadingListener() { @Override public void onLoadingComplete(String s, View view, Bitmap bitmap) { displayPhoto(bitmap); } }, new ImageLoadingProgressListener() { @Override public void onProgressUpdate(String imageUri, View view, int current, int total) { android.util.Log.d("photoviewfragment", "update : " + current + "/" + total); } }); } private void displayPhoto(Bitmap data) { bindPhoto(data); } /** * Binds an image to the photo view. */ private void bindPhoto(Bitmap bitmap) { if (bitmap != null) { if (mPhotoView != null) { mPhotoView.bindPhoto(bitmap); } enableImageTransforms(true); } } /** * Enable or disable image transformations. When transformations are enabled, this view * consumes all touch events. */ public void enableImageTransforms(boolean enable) { if (mPhotoView != null) { mPhotoView.enableImageTransforms(enable); } } /** * Resets the photo view to it's default state w/ no bound photo. */ private void resetPhotoView() { if (mPhotoView != null) { mPhotoView.bindPhoto(null); } } @Override public void onClick(View v) { //Image Click } /** * Reset the views to their default states */ public void resetViews() { if (mPhotoView != null) { mPhotoView.resetTransformations(); } } /** * Returns {@code true} if a photo has been bound. Otherwise, returns {@code false}. */ public boolean isPhotoBound() { return (mPhotoView != null && mPhotoView.isPhotoBound()); } @Override public void onViewActivated() { if (!mCallback.isFragmentActive(this)) { // we're not in the foreground; reset our view resetViews(); } else { if (!isPhotoBound()) { startLoadBitmapTask(); } } } @Override public boolean onInterceptMoveLeft(float origX, float origY) { if (!mCallback.isFragmentActive(this)) { // we're not in the foreground; don't intercept any touches return false; } return (mPhotoView != null && mPhotoView.interceptMoveLeft(origX, origY)); } @Override public boolean onInterceptMoveRight(float origX, float origY) { if (!mCallback.isFragmentActive(this)) { // we're not in the foreground; don't intercept any touches return false; } return (mPhotoView != null && mPhotoView.interceptMoveRight(origX, origY)); } }