diff options
author | Andrew Sapperstein <asapperstein@google.com> | 2012-07-23 18:33:00 -0700 |
---|---|---|
committer | Andrew Sapperstein <asapperstein@google.com> | 2012-07-23 18:36:20 -0700 |
commit | d19540fb7139fc0baba3b55260a6aabdb029c831 (patch) | |
tree | 45fc0b51d8b3bf52598ed850b6631bbb1562e1ff | |
parent | a6729336171ef61950d5f585b0f39c013ae6dcbc (diff) | |
download | android_frameworks_ex-d19540fb7139fc0baba3b55260a6aabdb029c831.tar.gz android_frameworks_ex-d19540fb7139fc0baba3b55260a6aabdb029c831.tar.bz2 android_frameworks_ex-d19540fb7139fc0baba3b55260a6aabdb029c831.zip |
Support showing previews in the photo viewer.
The photo viewer now supports the notion of a
preview of the full image. The preview is not
pinchable in any manner and displays a circular
progress bar over top of it while we are downloading
the full version of the image.
To enable this functionality, there is a new column
in the PhotoContract API called thumbnailUri. If it is
not set to null and if the attempted load of the contentUri
is unsuccessful, we will attempt to load a thumbnail version
that will show until the contentUri is finished loading.
Change-Id: I5547a5fc6a30ee6a30f137dc1dee76a77fb5b304
5 files changed, 69 insertions, 44 deletions
diff --git a/photoviewer/src/com/android/ex/photo/Intents.java b/photoviewer/src/com/android/ex/photo/Intents.java index 18c626e..7e31169 100644 --- a/photoviewer/src/com/android/ex/photo/Intents.java +++ b/photoviewer/src/com/android/ex/photo/Intents.java @@ -35,6 +35,7 @@ public class Intents { public static final String EXTRA_RESOLVED_PHOTO_URI = "resolved_photo_uri"; public static final String EXTRA_PHOTO_NAME = "photo_name"; public static final String EXTRA_PROJECTION = "projection"; + public static final String EXTRA_THUMBNAIL_URI = "thumbnail_uri"; /** * Gets a photo view intent builder to display the photos from phone activity. @@ -76,6 +77,8 @@ public class Intents { private String mResolvedPhotoUri; /** The projection for the query to use; optional */ private String[] mProjection; + /** The URI of a thumbnail of the photo to display */ + private String mThumbnailUri; private PhotoViewIntentBuilder(Context context, Class<?> cls) { mIntent = new Intent(context, cls); @@ -115,6 +118,14 @@ public class Intents { return this; } + /** + * Sets the URI for a thumbnail preview of the photo. + */ + public PhotoViewIntentBuilder setThumbnailUri(String thumbnailUri) { + mThumbnailUri = thumbnailUri; + return this; + } + /** Build the intent */ public Intent build() { if (TextUtils.isEmpty(mPhotosUri) && TextUtils.isEmpty(mResolvedPhotoUri)) { @@ -146,6 +157,10 @@ public class Intents { mIntent.putExtra(EXTRA_PROJECTION, mProjection); } + if (mThumbnailUri != null) { + mIntent.putExtra(EXTRA_THUMBNAIL_URI, mThumbnailUri); + } + return mIntent; } } diff --git a/photoviewer/src/com/android/ex/photo/adapters/PhotoPagerAdapter.java b/photoviewer/src/com/android/ex/photo/adapters/PhotoPagerAdapter.java index 41b146e..0c7ba63 100644 --- a/photoviewer/src/com/android/ex/photo/adapters/PhotoPagerAdapter.java +++ b/photoviewer/src/com/android/ex/photo/adapters/PhotoPagerAdapter.java @@ -33,6 +33,7 @@ import com.android.ex.photo.provider.PhotoContract; public class PhotoPagerAdapter extends BaseCursorPagerAdapter { private int mContentUriIndex; private int mPhotoNameIndex; + private int mThumbnailUriIndex; public PhotoPagerAdapter(Context context, FragmentManager fm, Cursor c) { super(context, fm, c); @@ -42,13 +43,15 @@ public class PhotoPagerAdapter extends BaseCursorPagerAdapter { public Fragment getItem(Context context, Cursor cursor, int position) { final String photoUri = cursor.getString(mContentUriIndex); final String photoName = cursor.getString(mPhotoNameIndex); + final String thumbnailUri = cursor.getString(mThumbnailUriIndex); // create new PhotoViewFragment final PhotoViewIntentBuilder builder = Intents.newPhotoViewFragmentIntentBuilder(mContext); builder .setPhotoName(photoName) - .setResolvedPhotoUri(photoUri); + .setResolvedPhotoUri(photoUri) + .setThumbnailUri(thumbnailUri); return new PhotoViewFragment(builder.build(), position, this); } @@ -57,6 +60,8 @@ public class PhotoPagerAdapter extends BaseCursorPagerAdapter { public Cursor swapCursor(Cursor newCursor) { mContentUriIndex = newCursor.getColumnIndex(PhotoContract.PhotoViewColumns.CONTENT_URI); + mThumbnailUriIndex = + newCursor.getColumnIndex(PhotoContract.PhotoViewColumns.THUMBNAIL_URI); mPhotoNameIndex = newCursor.getColumnIndex(PhotoContract.PhotoViewColumns.NAME); diff --git a/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java b/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java index 726dca4..36dd9da 100644 --- a/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java +++ b/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java @@ -77,13 +77,15 @@ public class PhotoViewFragment extends Fragment implements "com.android.mail.photo.fragments.PhotoViewFragment.INTENT"; // Loader IDs - private final static int LOADER_ID_PHOTO = 2; + private final static int LOADER_ID_PHOTO = 1; + private final static int LOADER_ID_THUMBNAIL = 2; /** The size of the photo */ public static Integer sPhotoSize; /** The URL of a photo to display */ private String mResolvedPhotoUri; + private String mThumbnailUri; /** The intent we were launched with */ private Intent mIntent; private PhotoViewActivity mCallback; @@ -95,6 +97,8 @@ public class PhotoViewFragment extends Fragment implements /** Whether or not the fragment should make the photo full-screen */ private boolean mFullScreen; + private boolean mShowingThumbnail; + public PhotoViewFragment() { mPosition = -1; } @@ -103,6 +107,7 @@ public class PhotoViewFragment extends Fragment implements mIntent = intent; mPosition = position; mAdapter = adapter; + mShowingThumbnail = false; } @Override @@ -151,8 +156,7 @@ public class PhotoViewFragment extends Fragment implements } mResolvedPhotoUri = mIntent.getStringExtra(Intents.EXTRA_RESOLVED_PHOTO_URI); - - setHasOptionsMenu(true); + mThumbnailUri = mIntent.getStringExtra(Intents.EXTRA_THUMBNAIL_URI); } @Override @@ -161,9 +165,6 @@ public class PhotoViewFragment extends Fragment implements final View view = inflater.inflate(R.layout.photo_fragment_view, container, false); mPhotoView = (PhotoView) view.findViewById(R.id.photo_view); - - mPhotoView.setPhotoLoading(true); - mPhotoView.setOnClickListener(this); mPhotoView.setFullScreen(mFullScreen, false); @@ -214,10 +215,13 @@ public class PhotoViewFragment extends Fragment implements @Override public Loader<Bitmap> onCreateLoader(int id, Bundle args) { - if (id == LOADER_ID_PHOTO) { - return new PhotoBitmapLoader(getActivity(), mResolvedPhotoUri); - } else { - return null; + switch (id) { + case LOADER_ID_PHOTO: + return new PhotoBitmapLoader(getActivity(), mResolvedPhotoUri); + case LOADER_ID_THUMBNAIL: + return new PhotoBitmapLoader(getActivity(), mThumbnailUri); + default: + return null; } } @@ -229,14 +233,31 @@ public class PhotoViewFragment extends Fragment implements } final int id = loader.getId(); - if (id == LOADER_ID_PHOTO) { - if (data == null) { - return; - } + switch (id) { + case LOADER_ID_PHOTO: + if (data == null) { + getLoaderManager().initLoader(LOADER_ID_THUMBNAIL, null, this); + return; + } + + mShowingThumbnail = false; + bindPhoto(data); + mCallback.setViewActivated(); + setViewVisibility(); + break; + case LOADER_ID_THUMBNAIL: + if (data == null || isPhotoBound()) { + return; + } - bindPhoto(data); - mCallback.setViewActivated(); - setViewVisibility(); + mShowingThumbnail = true; + bindPhoto(data); + mCallback.setViewActivated(); + setViewVisibility(); + mPhotoView.enableImageTransforms(false); + break; + default: + break; } } @@ -245,7 +266,6 @@ public class PhotoViewFragment extends Fragment implements */ private void bindPhoto(Bitmap bitmap) { if (mPhotoView != null) { - mPhotoView.setPhotoLoading(false); mPhotoView.bindPhoto(bitmap); } } @@ -255,7 +275,6 @@ public class PhotoViewFragment extends Fragment implements */ private void resetPhotoView() { if (mPhotoView != null) { - mPhotoView.setPhotoLoading(true); mPhotoView.bindPhoto(null); } } @@ -322,7 +341,7 @@ public class PhotoViewFragment extends Fragment implements * Returns {@code true} if a photo has been bound. Otherwise, returns {@code false}. */ public boolean isPhotoBound() { - return (mPhotoView != null && mPhotoView.isPhotoBound()); + return (mPhotoView != null && mPhotoView.isPhotoBound() && !mShowingThumbnail); } /** diff --git a/photoviewer/src/com/android/ex/photo/provider/PhotoContract.java b/photoviewer/src/com/android/ex/photo/provider/PhotoContract.java index 51ce893..0a9a43a 100644 --- a/photoviewer/src/com/android/ex/photo/provider/PhotoContract.java +++ b/photoviewer/src/com/android/ex/photo/provider/PhotoContract.java @@ -21,7 +21,7 @@ import android.net.Uri; import android.provider.OpenableColumns; public final class PhotoContract { - /** Columns for the view {@link #PHOTO_VIEW} */ + /** Columns for the view */ public static interface PhotoViewColumns { /** * This column is a {@link Uri} that can be queried @@ -39,6 +39,12 @@ public final class PhotoContract { */ public static final String CONTENT_URI = "contentUri"; /** + * This column is a {@link Uri} that points to a thumbnail of the image + * that ideally is a local file. + * This value is undefined in any other state. + */ + public static final String THUMBNAIL_URI = "thumbnailUri"; + /** * This string column is the MIME type. */ public static final String CONTENT_TYPE = "contentType"; @@ -51,13 +57,9 @@ public final class PhotoContract { PhotoViewColumns.URI, PhotoViewColumns.NAME, PhotoViewColumns.CONTENT_URI, + PhotoViewColumns.THUMBNAIL_URI, PhotoViewColumns.CONTENT_TYPE, }; - - public final static int INDEX_URI = 0; - public final static int INDEX_NAME = 1; - public final static int INDEX_CONTENT_URI = 2; - public final static int INDEX_CONTENT_TYPE = 3; } public static final class ContentTypeParameters { diff --git a/photoviewer/src/com/android/ex/photo/views/PhotoView.java b/photoviewer/src/com/android/ex/photo/views/PhotoView.java index f6b8315..1de5ff4 100644 --- a/photoviewer/src/com/android/ex/photo/views/PhotoView.java +++ b/photoviewer/src/com/android/ex/photo/views/PhotoView.java @@ -86,8 +86,6 @@ public class PhotoView extends View implements GestureDetector.OnGestureListener /** The photo to display */ private BitmapDrawable mDrawable; - /** Whether or not the photo is in the process of loading */ - private boolean mLoading; /** The matrix used for drawing; this may be {@code null} */ private Matrix mDrawMatrix; /** A matrix to apply the scaling of the photo */ @@ -469,20 +467,6 @@ public class PhotoView extends View implements GestureDetector.OnGestureListener } /** - * Returns {@code true} if a photo has been bound. Otherwise, {@code false}. - */ - public boolean isPhotoLoading() { - return mLoading; - } - - /** - * Sets whether the photo is being loaded. - */ - public void setPhotoLoading(boolean loading) { - mLoading = loading; - } - - /** * Hides the photo info portion of the header. As a side effect, this automatically enables * or disables image transformations [eg zoom, pan, etc...] depending upon the value of * fullScreen. If this is not desirable, enable / disable image transformations manually. @@ -550,7 +534,7 @@ public class PhotoView extends View implements GestureDetector.OnGestureListener // snap transformations; we don't animate mMatrix.set(mOriginalMatrix); - // Invalidate the view because if you move off this PhotoHeaderView + // Invalidate the view because if you move off this PhotoView // to another one and come back, you want it to draw from scratch // in case you were zoomed in or translated (since those settings // are not preserved and probably shouldn't be). |