1f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein/* 2f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Copyright (C) 2011 Google Inc. 3f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Licensed to The Android Open Source Project. 4f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 5f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Licensed under the Apache License, Version 2.0 (the "License"); 6f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * you may not use this file except in compliance with the License. 7f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * You may obtain a copy of the License at 8f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 9f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * http://www.apache.org/licenses/LICENSE-2.0 10f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 11f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Unless required by applicable law or agreed to in writing, software 12f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * distributed under the License is distributed on an "AS IS" BASIS, 13f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * See the License for the specific language governing permissions and 15f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * limitations under the License. 16f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 17f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 18f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinpackage com.android.ex.photo.fragments; 19f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 20f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.app.Activity; 21f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.content.Context; 22f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.content.Intent; 230c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sappersteinimport android.database.Cursor; 24f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.graphics.Bitmap; 25f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.os.Bundle; 26fc3a6f46f375ef9347f57b88fd7e0c8b62ce1058Martin Hibdonimport android.os.Handler; 278746927a945358bb9e515985a37cac7807261026Martin Hibdonimport android.support.v4.app.Fragment; 288746927a945358bb9e515985a37cac7807261026Martin Hibdonimport android.support.v4.app.LoaderManager; 298746927a945358bb9e515985a37cac7807261026Martin Hibdonimport android.support.v4.content.Loader; 30f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.util.DisplayMetrics; 31f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.view.LayoutInflater; 32f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.view.View; 33f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.view.View.OnClickListener; 34f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.view.ViewGroup; 35f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.view.WindowManager; 369007d640832f674a9d65058a3c2a484c078d239eAndrew Sappersteinimport android.widget.ImageView; 37150e623129eef49467f1d6f67649e4636a4513f2Andrew Sappersteinimport android.widget.ProgressBar; 38150e623129eef49467f1d6f67649e4636a4513f2Andrew Sappersteinimport android.widget.TextView; 39f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 40f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.Intents; 41399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdonimport com.android.ex.photo.PhotoViewCallbacks; 42399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdonimport com.android.ex.photo.PhotoViewCallbacks.CursorChangedListener; 43399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdonimport com.android.ex.photo.PhotoViewCallbacks.OnScreenListener; 44f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.R; 450c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sappersteinimport com.android.ex.photo.adapters.PhotoPagerAdapter; 46f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.loaders.PhotoBitmapLoader; 47f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.util.ImageUtils; 48f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.views.PhotoView; 49150e623129eef49467f1d6f67649e4636a4513f2Andrew Sappersteinimport com.android.ex.photo.views.ProgressBarWrapper; 50f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 51f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein/** 52f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Displays a photo. 53f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 54f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinpublic class PhotoViewFragment extends Fragment implements 558746927a945358bb9e515985a37cac7807261026Martin Hibdon LoaderManager.LoaderCallbacks<Bitmap>, OnClickListener, OnScreenListener, CursorChangedListener { 56f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 57f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Interface for components that are internally scrollable left-to-right. 58f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 59f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public static interface HorizontallyScrollable { 60f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 61f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Return {@code true} if the component needs to receive right-to-left 62f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * touch movements. 63f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 64f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @param origX the raw x coordinate of the initial touch 65f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @param origY the raw y coordinate of the initial touch 66f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 67f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 68f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean interceptMoveLeft(float origX, float origY); 69f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 70f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 71f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Return {@code true} if the component needs to receive left-to-right 72f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * touch movements. 73f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 74f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @param origX the raw x coordinate of the initial touch 75f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @param origY the raw y coordinate of the initial touch 76f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 77f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean interceptMoveRight(float origX, float origY); 78f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 79f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 80934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected final static String STATE_INTENT_KEY = 81f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein "com.android.mail.photo.fragments.PhotoViewFragment.INTENT"; 82f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 83f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Loader IDs 84bf77f3b89ad05406eecb30c2ea9390f7e921de32Martin Hibdon protected final static int LOADER_ID_PHOTO = 1; 85bf77f3b89ad05406eecb30c2ea9390f7e921de32Martin Hibdon protected final static int LOADER_ID_THUMBNAIL = 2; 86f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 87f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The size of the photo */ 88f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public static Integer sPhotoSize; 89f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 90f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The URL of a photo to display */ 91934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected String mResolvedPhotoUri; 92934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected String mThumbnailUri; 93f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The intent we were launched with */ 94934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected Intent mIntent; 95934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected PhotoViewCallbacks mCallback; 96934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected PhotoPagerAdapter mAdapter; 97f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 98934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected PhotoView mPhotoView; 99934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected ImageView mPhotoPreviewImage; 100934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected TextView mEmptyText; 101934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected ImageView mRetryButton; 102934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected ProgressBarWrapper mPhotoProgressBar; 103150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 104934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected final int mPosition; 105f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 106f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Whether or not the fragment should make the photo full-screen */ 107934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected boolean mFullScreen; 108f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 109ae78bbd1c97e702147b29966903ca6e08ed3616fAdam Copp /** Whether or not this fragment will only show the loading spinner */ 110934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected final boolean mOnlyShowSpinner; 111ae78bbd1c97e702147b29966903ca6e08ed3616fAdam Copp 1129556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook /** Whether or not the progress bar is showing valid information about the progress stated */ 113934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected boolean mProgressBarNeeded = true; 1149556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook 115934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon protected View mPhotoPreviewAndProgress; 116928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein 117f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public PhotoViewFragment() { 1180c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mPosition = -1; 119ae78bbd1c97e702147b29966903ca6e08ed3616fAdam Copp mOnlyShowSpinner = false; 1209556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook mProgressBarNeeded = true; 121f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 122f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 123ae78bbd1c97e702147b29966903ca6e08ed3616fAdam Copp public PhotoViewFragment(Intent intent, int position, PhotoPagerAdapter adapter, 124ae78bbd1c97e702147b29966903ca6e08ed3616fAdam Copp boolean onlyShowSpinner) { 125f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mIntent = intent; 1260c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mPosition = position; 1270c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mAdapter = adapter; 128ae78bbd1c97e702147b29966903ca6e08ed3616fAdam Copp mOnlyShowSpinner = onlyShowSpinner; 1299556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook mProgressBarNeeded = true; 130f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 131f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 132f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 133f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onAttach(Activity activity) { 134f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onAttach(activity); 135399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon mCallback = (PhotoViewCallbacks) activity; 136f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mCallback == null) { 137150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein throw new IllegalArgumentException( 138150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein "Activity must be a derived class of PhotoViewActivity"); 139f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 140f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 141f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (sPhotoSize == null) { 142f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final DisplayMetrics metrics = new DisplayMetrics(); 143f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final WindowManager wm = 144f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE); 145f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final ImageUtils.ImageSize imageSize = ImageUtils.sUseImageSize; 146f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein wm.getDefaultDisplay().getMetrics(metrics); 147f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein switch (imageSize) { 148f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein case EXTRA_SMALL: { 149f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Use a photo that's 80% of the "small" size 150f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein sPhotoSize = (Math.min(metrics.heightPixels, metrics.widthPixels) * 800) / 1000; 151f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein break; 152f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 153f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 154f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein case SMALL: 155f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein case NORMAL: 156f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein default: { 157f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein sPhotoSize = Math.min(metrics.heightPixels, metrics.widthPixels); 158f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein break; 159f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 160f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 161f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 162f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 163f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 164f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 165f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onDetach() { 166f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mCallback = null; 167f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onDetach(); 168f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 169f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 170f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 171f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onCreate(Bundle savedInstanceState) { 172f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onCreate(savedInstanceState); 173f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 174f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (savedInstanceState != null) { 175c4d9382e8e52e1122d51f52402c6c4a609a785d6Mark Wei final Bundle state = savedInstanceState.getBundle(STATE_INTENT_KEY); 176c4d9382e8e52e1122d51f52402c6c4a609a785d6Mark Wei if (state != null) { 177c4d9382e8e52e1122d51f52402c6c4a609a785d6Mark Wei mIntent = new Intent().putExtras(state); 178c4d9382e8e52e1122d51f52402c6c4a609a785d6Mark Wei } 179f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 180f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 1812539f2ef0fa351d40551dda5ba0b543b2a042b0fMark Wei if (mIntent != null) { 1822539f2ef0fa351d40551dda5ba0b543b2a042b0fMark Wei mResolvedPhotoUri = mIntent.getStringExtra(Intents.EXTRA_RESOLVED_PHOTO_URI); 1832539f2ef0fa351d40551dda5ba0b543b2a042b0fMark Wei mThumbnailUri = mIntent.getStringExtra(Intents.EXTRA_THUMBNAIL_URI); 1842539f2ef0fa351d40551dda5ba0b543b2a042b0fMark Wei } 185f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 186f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 187f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 188f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public View onCreateView(LayoutInflater inflater, ViewGroup container, 189f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein Bundle savedInstanceState) { 190f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final View view = inflater.inflate(R.layout.photo_fragment_view, container, false); 191f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 192f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoView = (PhotoView) view.findViewById(R.id.photo_view); 19391dbfd25cc234de393ae22fc39a832a6335e1bc2Adam Copp mPhotoView.setMaxInitialScale(mIntent.getFloatExtra(Intents.EXTRA_MAX_INITIAL_SCALE, 1)); 194f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoView.setOnClickListener(this); 195f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoView.setFullScreen(mFullScreen, false); 196edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp mPhotoView.enableImageTransforms(false); 1979007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein 198150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mPhotoPreviewAndProgress = view.findViewById(R.id.photo_preview); 199150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mPhotoPreviewImage = (ImageView) view.findViewById(R.id.photo_preview_image); 200150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein final ProgressBar indeterminate = 201150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein (ProgressBar) view.findViewById(R.id.indeterminate_progress); 202150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein final ProgressBar determinate = 203150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein (ProgressBar) view.findViewById(R.id.determinate_progress); 204150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mPhotoProgressBar = new ProgressBarWrapper(determinate, indeterminate, true); 205150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mEmptyText = (TextView) view.findViewById(R.id.empty_text); 206150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mRetryButton = (ImageView) view.findViewById(R.id.retry_button); 207f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 208f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Don't call until we've setup the entire view 209f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein setViewVisibility(); 210f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 211f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return view; 212f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 213f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 214f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 215f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onResume() { 216f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mCallback.addScreenListener(this); 2170c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mCallback.addCursorListener(this); 218f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 219bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp getLoaderManager().initLoader(LOADER_ID_THUMBNAIL, null, this); 220f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 221f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onResume(); 222f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 223f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 224f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 225f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onPause() { 226f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onPause(); 2270c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein // Remove listeners 2280c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mCallback.removeCursorListener(this); 229f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mCallback.removeScreenListener(this); 230f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein resetPhotoView(); 231f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 232f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 233f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 234f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onDestroyView() { 235f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Clean up views and other components 236f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mPhotoView != null) { 237f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoView.clear(); 238f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoView = null; 239f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 240f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 241f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onDestroyView(); 242f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 243f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 244f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 245f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onSaveInstanceState(Bundle outState) { 246f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onSaveInstanceState(outState); 247f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 248f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mIntent != null) { 249f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein outState.putParcelable(STATE_INTENT_KEY, mIntent.getExtras()); 250f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 251f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 252f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 253f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 254f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public Loader<Bitmap> onCreateLoader(int id, Bundle args) { 255ae78bbd1c97e702147b29966903ca6e08ed3616fAdam Copp if(mOnlyShowSpinner) { 256ae78bbd1c97e702147b29966903ca6e08ed3616fAdam Copp return null; 257ae78bbd1c97e702147b29966903ca6e08ed3616fAdam Copp } 258928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein switch (id) { 259928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein case LOADER_ID_PHOTO: 260928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein return new PhotoBitmapLoader(getActivity(), mResolvedPhotoUri); 261928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein case LOADER_ID_THUMBNAIL: 262928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein return new PhotoBitmapLoader(getActivity(), mThumbnailUri); 263928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein default: 264928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein return null; 265f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 266f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 267f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 268f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 269f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onLoadFinished(Loader<Bitmap> loader, Bitmap data) { 270f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // If we don't have a view, the fragment has been paused. We'll get the cursor again later. 271f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (getView() == null) { 272f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return; 273f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 274f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 275f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int id = loader.getId(); 276928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein switch (id) { 277928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein case LOADER_ID_PHOTO: 2789556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook if (data != null) { 279150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein bindPhoto(data); 280edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp enableImageTransforms(true); 281150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mPhotoPreviewAndProgress.setVisibility(View.GONE); 2829556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook mProgressBarNeeded = false; 2839556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook } else { 2849556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook // Received a null result for the full size image. Instead attempt to load the 2859556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook // thumbnail 286fc3a6f46f375ef9347f57b88fd7e0c8b62ce1058Martin Hibdon Handler handler = new Handler(); 287fc3a6f46f375ef9347f57b88fd7e0c8b62ce1058Martin Hibdon handler.post(new Runnable() { 288fc3a6f46f375ef9347f57b88fd7e0c8b62ce1058Martin Hibdon @Override 289fc3a6f46f375ef9347f57b88fd7e0c8b62ce1058Martin Hibdon public void run() { 290fc3a6f46f375ef9347f57b88fd7e0c8b62ce1058Martin Hibdon getLoaderManager().initLoader(LOADER_ID_THUMBNAIL, null, 291fc3a6f46f375ef9347f57b88fd7e0c8b62ce1058Martin Hibdon PhotoViewFragment.this); 292fc3a6f46f375ef9347f57b88fd7e0c8b62ce1058Martin Hibdon } 293fc3a6f46f375ef9347f57b88fd7e0c8b62ce1058Martin Hibdon }); 294928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein } 295928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein break; 296928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein case LOADER_ID_THUMBNAIL: 2971389ae2ea3376b317e4810f9e3b123a0cb5ac008Adam Copp mProgressBarNeeded = false; 2989007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein if (isPhotoBound()) { 2999556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook // There is need to do anything with the thumbnail image, as the full size 3009556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook // image is being shown. 3019556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook mPhotoPreviewAndProgress.setVisibility(View.GONE); 3029007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein return; 303150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } else if (data == null) { 3049007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein // no preview, show default 305150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mPhotoPreviewImage.setVisibility(View.VISIBLE); 306150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mPhotoPreviewImage.setImageResource(R.drawable.default_image); 307150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } else { 308bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp bindPhoto(data); 309edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp enableImageTransforms(false); 310535ffb18682c17d08be17aae5a31c11bf9d44ae5Mike Dodd Handler handler = new Handler(); 311535ffb18682c17d08be17aae5a31c11bf9d44ae5Mike Dodd handler.post(new Runnable() { 312535ffb18682c17d08be17aae5a31c11bf9d44ae5Mike Dodd @Override 313535ffb18682c17d08be17aae5a31c11bf9d44ae5Mike Dodd public void run() { 314535ffb18682c17d08be17aae5a31c11bf9d44ae5Mike Dodd getLoaderManager().initLoader(LOADER_ID_PHOTO, null, 315535ffb18682c17d08be17aae5a31c11bf9d44ae5Mike Dodd PhotoViewFragment.this); 316535ffb18682c17d08be17aae5a31c11bf9d44ae5Mike Dodd } 317535ffb18682c17d08be17aae5a31c11bf9d44ae5Mike Dodd }); 318928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein } 319928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein break; 320928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein default: 321928a39fb533255b34145285fabbd4f51961df63aAndrew Sapperstein break; 322f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 323150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 3249556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook if (mProgressBarNeeded == false) { 3259556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook // Hide the progress bar as it isn't needed anymore. 3269556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook mPhotoProgressBar.setVisibility(View.GONE); 3279556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook } 3289556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook 329150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mCallback.setViewActivated(); 330150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein setViewVisibility(); 331f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 332f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 333f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 334f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Binds an image to the photo view. 335f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 336f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private void bindPhoto(Bitmap bitmap) { 337f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mPhotoView != null) { 338f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoView.bindPhoto(bitmap); 339f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 340f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 341f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 342f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 343edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp * Enable or disable image transformations. When transformations are enabled, this view 344edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp * consumes all touch events. 345edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp */ 346edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp public void enableImageTransforms(boolean enable) { 347edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp mPhotoView.enableImageTransforms(enable); 348edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp } 349edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp 350edad0e0512af73ea89b85c5e4568a42bdae3f539Adam Copp /** 351f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Resets the photo view to it's default state w/ no bound photo. 352f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 353f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private void resetPhotoView() { 354f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mPhotoView != null) { 355f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoView.bindPhoto(null); 356f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 357f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 358f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 359f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 360f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onLoaderReset(Loader<Bitmap> loader) { 361f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Do nothing 362f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 363f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 364f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 365f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onClick(View v) { 3661abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein mCallback.toggleFullScreen(); 367f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 368f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 369f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 3701abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein public void onFullScreenChanged(boolean fullScreen) { 371f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein setViewVisibility(); 372f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 373f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 374f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 375f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onViewActivated() { 376f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (!mCallback.isFragmentActive(this)) { 377f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // we're not in the foreground; reset our view 378f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein resetViews(); 379f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 380f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mCallback.onFragmentVisible(this); 381f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 382f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 383f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 384f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 385f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Reset the views to their default states 386f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 387f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void resetViews() { 388f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mPhotoView != null) { 389f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoView.resetTransformations(); 390f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 391f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 392f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 393f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 394f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean onInterceptMoveLeft(float origX, float origY) { 395f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (!mCallback.isFragmentActive(this)) { 396f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // we're not in the foreground; don't intercept any touches 397f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return false; 398f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 399f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 400f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return (mPhotoView != null && mPhotoView.interceptMoveLeft(origX, origY)); 401f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 402f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 403f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 404f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean onInterceptMoveRight(float origX, float origY) { 405f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (!mCallback.isFragmentActive(this)) { 406f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // we're not in the foreground; don't intercept any touches 407f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return false; 408f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 409f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 410f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return (mPhotoView != null && mPhotoView.interceptMoveRight(origX, origY)); 411f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 412f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 413f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 414f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Returns {@code true} if a photo has been bound. Otherwise, returns {@code false}. 415f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 416f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean isPhotoBound() { 417150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein return (mPhotoView != null && mPhotoView.isPhotoBound()); 418f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 419f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 420f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 421f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Sets view visibility depending upon whether or not we're in "full screen" mode. 422f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 423f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private void setViewVisibility() { 424f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final boolean fullScreen = mCallback.isFragmentFullScreen(this); 425f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final boolean hide = fullScreen; 426f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 427f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein setFullScreen(hide); 428f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 429f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 430f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 431f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Sets full-screen mode for the views. 432f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 433f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void setFullScreen(boolean fullScreen) { 434f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mFullScreen = fullScreen; 435f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 4360c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 4370c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein @Override 4380c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public void onCursorChanged(Cursor cursor) { 4390c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein if (cursor.moveToPosition(mPosition) && !isPhotoBound()) { 4400c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein final LoaderManager manager = getLoaderManager(); 4410c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein final Loader<Bitmap> fakeLoader = manager.getLoader(LOADER_ID_PHOTO); 4420c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein if (fakeLoader == null) { 4430c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein return; 4440c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 4450c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 4460c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein final PhotoBitmapLoader loader = 4470c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein (PhotoBitmapLoader) fakeLoader; 4480c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mResolvedPhotoUri = mAdapter.getPhotoUri(cursor); 4490c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein loader.setPhotoUri(mResolvedPhotoUri); 4500c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein loader.forceLoad(); 4510c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 4520c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 453150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 454150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein public ProgressBarWrapper getPhotoProgressBar() { 455150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein return mPhotoProgressBar; 456150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 457150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 458150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein public TextView getEmptyText() { 459150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein return mEmptyText; 460150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 461150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 462150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein public ImageView getRetryButton() { 463150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein return mRetryButton; 464150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 4659556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook 4669556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook public boolean isProgressBarNeeded() { 4679556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook return mProgressBarNeeded; 4689556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook } 469f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein} 470