diff options
author | Andrew Sapperstein <asapperstein@google.com> | 2012-08-03 13:44:57 -0700 |
---|---|---|
committer | Andrew Sapperstein <asapperstein@google.com> | 2012-08-03 14:41:50 -0700 |
commit | 509bd03a2a783f804e9456767b52e0f8ef43479b (patch) | |
tree | 47952020b5f9e0b5a2a7d71e4c935c09bb4f23dd /photoviewer/src | |
parent | b81f8c963a0d97034872f14f4e2294d1e2b44da1 (diff) | |
download | android_frameworks_ex-509bd03a2a783f804e9456767b52e0f8ef43479b.tar.gz android_frameworks_ex-509bd03a2a783f804e9456767b52e0f8ef43479b.tar.bz2 android_frameworks_ex-509bd03a2a783f804e9456767b52e0f8ef43479b.zip |
Enabled optional support for showing progress.
Added some progress bars to the "empty" view
so that implementors of the API can show the
progress of things like downloads or loading.
Additionally, added a retry button and an optional
text that allows you to indicate status to the user.
Due to a bug in the framework, we actually use two
progress bars (one determinate and one indeterminate)
to update our status. Created a wrapper that allows
the controlling of both progress bars in sync.
Change-Id: I710e06317948d376d445abf1603545982ac8479d
Diffstat (limited to 'photoviewer/src')
3 files changed, 142 insertions, 40 deletions
diff --git a/photoviewer/src/com/android/ex/photo/PhotoViewActivity.java b/photoviewer/src/com/android/ex/photo/PhotoViewActivity.java index 170a9eb..aa8029e 100644 --- a/photoviewer/src/com/android/ex/photo/PhotoViewActivity.java +++ b/photoviewer/src/com/android/ex/photo/PhotoViewActivity.java @@ -18,6 +18,7 @@ package com.android.ex.photo; import android.app.ActionBar; +import android.app.ActionBar.OnMenuVisibilityListener; import android.app.Activity; import android.app.ActivityManager; import android.app.Fragment; @@ -48,7 +49,7 @@ import java.util.Set; */ public class PhotoViewActivity extends Activity implements LoaderCallbacks<Cursor>, OnPageChangeListener, OnInterceptTouchListener, - OnFragmentPagerListener { + OnFragmentPagerListener, OnMenuVisibilityListener { /** * Listener to be invoked for screen events. @@ -205,6 +206,8 @@ public class PhotoViewActivity extends Activity implements actionBar.setDisplayHomeAsUpEnabled(true); mActionBarHideDelayTime = getResources().getInteger( R.integer.action_bar_delay_time_in_millis); + actionBar.addOnMenuVisibilityListener(this); + mActionBarHideHandler = new Handler(); } @Override @@ -328,7 +331,7 @@ public class PhotoViewActivity extends Activity implements notifyCursorListeners(data); mViewPager.setCurrentItem(itemIndex, false); - updateActionBar(); + setViewActivated(); } }); } @@ -353,9 +356,8 @@ public class PhotoViewActivity extends Activity implements @Override public void onPageSelected(int position) { - setViewActivated(); - updateActionBar(); mPhotoIndex = position; + setViewActivated(); } @Override @@ -375,6 +377,7 @@ public class PhotoViewActivity extends Activity implements } public void onFragmentVisible(PhotoViewFragment fragment) { + updateActionBar(fragment); } @Override @@ -412,18 +415,11 @@ public class PhotoViewActivity extends Activity implements if (mFullScreen) { setLightsOutMode(true); - if (mActionBarHideHandler == null) { - mActionBarHideHandler = new Handler(); - } - mActionBarHideHandler.removeCallbacks(mActionBarHideRunnable); + cancelActionBarHideRunnable(); } else { setLightsOutMode(false); if (setDelayedRunnable) { - if (mActionBarHideHandler == null) { - mActionBarHideHandler = new Handler(); - } - mActionBarHideHandler.postDelayed(mActionBarHideRunnable, - mActionBarHideDelayTime); + postActionBarHideRunnableWithDelay(); } } @@ -434,6 +430,15 @@ public class PhotoViewActivity extends Activity implements } } + private void postActionBarHideRunnableWithDelay() { + mActionBarHideHandler.postDelayed(mActionBarHideRunnable, + mActionBarHideDelayTime); + } + + private void cancelActionBarHideRunnable() { + mActionBarHideHandler.removeCallbacks(mActionBarHideRunnable); + } + private void setLightsOutMode(boolean enabled) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { int flags = enabled @@ -476,7 +481,7 @@ public class PhotoViewActivity extends Activity implements /** * Adjusts the activity title and subtitle to reflect the photo name and count. */ - protected void updateActionBar() { + protected void updateActionBar(PhotoViewFragment fragment) { final int position = mViewPager.getCurrentItem() + 1; final String subtitle; final boolean hasAlbumCount = mAlbumCount >= 0; @@ -526,4 +531,13 @@ public class PhotoViewActivity extends Activity implements public Cursor getCursor() { return (mAdapter == null) ? null : mAdapter.getCursor(); } + + @Override + public void onMenuVisibilityChanged(boolean isVisible) { + if (isVisible) { + cancelActionBarHideRunnable(); + } else { + postActionBarHideRunnableWithDelay(); + } + } } diff --git a/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java b/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java index 8479f2c..b8bfd4f 100644 --- a/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java +++ b/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java @@ -19,6 +19,7 @@ package com.android.ex.photo.fragments; import android.app.Activity; import android.app.Fragment; +import android.app.LoaderManager; import android.app.LoaderManager.LoaderCallbacks; import android.content.Context; import android.content.Intent; @@ -26,7 +27,6 @@ import android.content.Loader; import android.database.Cursor; import android.graphics.Bitmap; import android.os.Bundle; -import android.app.LoaderManager; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; @@ -34,6 +34,8 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; import com.android.ex.photo.Intents; import com.android.ex.photo.PhotoViewActivity; @@ -44,6 +46,7 @@ import com.android.ex.photo.adapters.PhotoPagerAdapter; import com.android.ex.photo.loaders.PhotoBitmapLoader; import com.android.ex.photo.util.ImageUtils; import com.android.ex.photo.views.PhotoView; +import com.android.ex.photo.views.ProgressBarWrapper; /** * Displays a photo. @@ -93,13 +96,17 @@ public class PhotoViewFragment extends Fragment implements private PhotoPagerAdapter mAdapter; private PhotoView mPhotoView; - private ImageView mPhotoPreview; + private ImageView mPhotoPreviewImage; + private TextView mEmptyText; + private ImageView mRetryButton; + private ProgressBarWrapper mPhotoProgressBar; + private final int mPosition; /** Whether or not the fragment should make the photo full-screen */ private boolean mFullScreen; - private boolean mShowingThumbnail; + private View mPhotoPreviewAndProgress; public PhotoViewFragment() { mPosition = -1; @@ -109,7 +116,6 @@ public class PhotoViewFragment extends Fragment implements mIntent = intent; mPosition = position; mAdapter = adapter; - mShowingThumbnail = false; } @Override @@ -117,7 +123,8 @@ public class PhotoViewFragment extends Fragment implements super.onAttach(activity); mCallback = (PhotoViewActivity) activity; if (mCallback == null) { - throw new IllegalArgumentException("Activity must be a derived class of PhotoViewActivity"); + throw new IllegalArgumentException( + "Activity must be a derived class of PhotoViewActivity"); } if (sPhotoSize == null) { @@ -171,7 +178,15 @@ public class PhotoViewFragment extends Fragment implements mPhotoView.setFullScreen(mFullScreen, false); mPhotoView.enableImageTransforms(true); - mPhotoPreview = (ImageView) view.findViewById(R.id.photo_preview_image); + mPhotoPreviewAndProgress = view.findViewById(R.id.photo_preview); + mPhotoPreviewImage = (ImageView) view.findViewById(R.id.photo_preview_image); + final ProgressBar indeterminate = + (ProgressBar) view.findViewById(R.id.indeterminate_progress); + final ProgressBar determinate = + (ProgressBar) view.findViewById(R.id.determinate_progress); + mPhotoProgressBar = new ProgressBarWrapper(determinate, indeterminate, true); + mEmptyText = (TextView) view.findViewById(R.id.empty_text); + mRetryButton = (ImageView) view.findViewById(R.id.retry_button); // Don't call until we've setup the entire view setViewVisibility(); @@ -242,36 +257,29 @@ public class PhotoViewFragment extends Fragment implements case LOADER_ID_PHOTO: if (data == null) { getLoaderManager().initLoader(LOADER_ID_THUMBNAIL, null, this); - return; + } else { + bindPhoto(data); + mPhotoPreviewAndProgress.setVisibility(View.GONE); } - - mShowingThumbnail = false; - bindPhoto(data); - mCallback.setViewActivated(); - setViewVisibility(); - mPhotoPreview.setVisibility(View.GONE); break; case LOADER_ID_THUMBNAIL: if (isPhotoBound()) { return; - } - - if (data == null) { + } else if (data == null) { // no preview, show default - mPhotoPreview.setVisibility(View.VISIBLE); - mPhotoPreview.setImageResource(R.drawable.default_image); - return; + mPhotoPreviewImage.setVisibility(View.VISIBLE); + mPhotoPreviewImage.setImageResource(R.drawable.default_image); + } else { + mPhotoPreviewImage.setVisibility(View.VISIBLE); + mPhotoPreviewImage.setImageBitmap(data); } - - mShowingThumbnail = true; - mPhotoPreview.setVisibility(View.VISIBLE); - mPhotoPreview.setImageBitmap(data); - mCallback.setViewActivated(); - setViewVisibility(); break; default: break; } + + mCallback.setViewActivated(); + setViewVisibility(); } /** @@ -350,7 +358,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() && !mShowingThumbnail); + return (mPhotoView != null && mPhotoView.isPhotoBound()); } /** @@ -386,4 +394,16 @@ public class PhotoViewFragment extends Fragment implements loader.forceLoad(); } } + + public ProgressBarWrapper getPhotoProgressBar() { + return mPhotoProgressBar; + } + + public TextView getEmptyText() { + return mEmptyText; + } + + public ImageView getRetryButton() { + return mRetryButton; + } } diff --git a/photoviewer/src/com/android/ex/photo/views/ProgressBarWrapper.java b/photoviewer/src/com/android/ex/photo/views/ProgressBarWrapper.java new file mode 100644 index 0000000..77b9000 --- /dev/null +++ b/photoviewer/src/com/android/ex/photo/views/ProgressBarWrapper.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012 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.android.ex.photo.views; + +import android.view.View; +import android.widget.ProgressBar; + +/** + * This class wraps around two progress bars and is solely designed to fix + * a bug in the framework (b/6928449) that prevents a progress bar from + * gracefully switching back and forth between indeterminate and determinate + * modes. + */ +public class ProgressBarWrapper { + private ProgressBar mDeterminate; + private ProgressBar mIndeterminate; + private boolean mIsIndeterminate; + + public ProgressBarWrapper(ProgressBar determinate, + ProgressBar indeterminate, boolean isIndeterminate) { + mDeterminate = determinate; + mIndeterminate = indeterminate; + setIndeterminate(isIndeterminate); + } + + public void setIndeterminate(boolean isIndeterminate) { + mIsIndeterminate = isIndeterminate; + + setVisibility(mIsIndeterminate); + } + + public void setVisibility(int visibility) { + if (visibility == View.INVISIBLE || visibility == View.GONE) { + mIndeterminate.setVisibility(visibility); + mDeterminate.setVisibility(visibility); + } else { + setVisibility(mIsIndeterminate); + } + } + + private void setVisibility(boolean isIndeterminate) { + mIndeterminate.setVisibility(isIndeterminate ? View.VISIBLE : View.GONE); + mDeterminate.setVisibility(isIndeterminate ? View.GONE : View.VISIBLE); + } + + public void setMax(int max) { + mDeterminate.setMax(max); + } + + public void setProgress(int progress) { + mDeterminate.setProgress(progress); + } +} |