diff options
-rw-r--r-- | AndroidManifest.xml | 1 | ||||
-rw-r--r-- | res/layout-land/camera_controls.xml | 3 | ||||
-rw-r--r-- | res/layout-port/camera_controls.xml | 3 | ||||
-rw-r--r-- | res/values/strings.xml | 5 | ||||
-rw-r--r-- | src/com/android/camera/CameraActivity.java | 12 | ||||
-rw-r--r-- | src/com/android/camera/ui/FilmStripView.java | 136 |
6 files changed, 118 insertions, 42 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d389b3c39..757c8b3e0 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -34,7 +34,6 @@ <application android:name="com.android.camera.app.CameraApp" - android:backupAgent="com.android.camera.CameraBackupAgent" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher_camera" android:label="@string/app_name" diff --git a/res/layout-land/camera_controls.xml b/res/layout-land/camera_controls.xml index 14953320e..cf27af192 100644 --- a/res/layout-land/camera_controls.xml +++ b/res/layout-land/camera_controls.xml @@ -65,6 +65,7 @@ android:layout_width="@dimen/capture_size" android:layout_height="@dimen/capture_size" android:scaleType="centerInside" - android:layout_gravity="top|right" /> + android:layout_gravity="top|right" + android:contentDescription="@string/switch_photo_filmstrip" /> </com.android.camera.ui.CameraControls> diff --git a/res/layout-port/camera_controls.xml b/res/layout-port/camera_controls.xml index 03e896bc0..a98ddff25 100644 --- a/res/layout-port/camera_controls.xml +++ b/res/layout-port/camera_controls.xml @@ -65,6 +65,7 @@ android:layout_width="@dimen/capture_size" android:layout_height="@dimen/capture_size" android:scaleType="centerInside" - android:layout_gravity="top|right" /> + android:layout_gravity="top|right" + android:contentDescription="@string/switch_photo_filmstrip" /> </com.android.camera.ui.CameraControls> diff --git a/res/values/strings.xml b/res/values/strings.xml index 2d8684850..dcbc358a5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -213,7 +213,7 @@ <item quantity="other">%d seconds</item> </plurals> <string name="pref_camera_timer_sound_default">@string/setting_on_value</string> - <!-- Text followed by a checkbox to turn on/off sound effects during the countdown. [CHAR LIMIT = 16]--> + <!-- Text followed by a checkbox to turn on/off sound effects during the countdown. [CHAR LIMIT = 24]--> <string name="pref_camera_timer_sound_title">Beep during countdown</string> <!-- Entry of a on/off setting. The setting is turned off. [CHAR LIMIT=15] --> @@ -657,4 +657,7 @@ CHAR LIMIT = NONE] --> <!-- Label for the save button in the crop activity action bar [CHAR LIMIT=20] --> <string name="crop_save">Save</string> + <!-- Label for album filmstrip button --> + <string name="switch_photo_filmstrip">Filmstrip view</string> + </resources> diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index fcb24b5e7..7705e379e 100644 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -20,6 +20,7 @@ import android.animation.Animator; import android.annotation.TargetApi; import android.app.ActionBar; import android.app.Activity; +import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@ -779,10 +780,15 @@ public class CameraActivity extends Activity switch (item.getItemId()) { case android.R.id.home: // ActionBar's Up/Home button was clicked - if (!CameraUtil.launchGallery(CameraActivity.this)) { - mFilmStripView.getController().goToFirstItem(); + try { + if (!CameraUtil.launchGallery(CameraActivity.this)) { + mFilmStripView.getController().goToFirstItem(); + } + return true; + } catch (ActivityNotFoundException e) { + Log.w(TAG, "No activity found to handle APP_GALLERY category!"); + finish(); } - return true; case R.id.action_delete: removeData(currentDataId); return true; diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java index 75886df05..93707a1d5 100644 --- a/src/com/android/camera/ui/FilmStripView.java +++ b/src/com/android/camera/ui/FilmStripView.java @@ -903,11 +903,13 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { * Check the bounds of {@code mCenterX}. Always call this function after: * 1. Any changes to {@code mCenterX}. 2. Any size change of the view * items. + * + * @return Whether clamp happened. */ - private void clampCenterX() { + private boolean clampCenterX() { ViewItem curr = mViewItem[mCurrentItem]; if (curr == null) { - return; + return false; } boolean stopScroll = false; @@ -925,11 +927,9 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } if (stopScroll) { - if (mController.isScrolling()) { - mController.stopScrolling(true); - } mCenterX = curr.getCenterX(); } + return stopScroll; } private void adjustChildZOrder() { @@ -984,10 +984,12 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } /** - * Updates the visibility of the bottom controls depending on the current - * data item. + * Updates the visibility of the bottom controls. + * + * @param force update the bottom controls even if the current id + * has been checked for button visibilities */ - private void updateBottomControls() { + private void updateBottomControls(boolean force) { if (mBottomControls == null) { mBottomControls = (FilmstripBottomControls) ((View) getParent()) .findViewById(R.id.filmstrip_bottom_controls); @@ -997,10 +999,14 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { final int requestId = getCurrentId(); - // Check if the item has changed since the last time we updated the - // visibility status. Only then check of the current image is a photo - // sphere. - if (requestId == mLastItemId || requestId < 0) { + if (requestId < 0) { + return; + } + + // If not a forced update, check if the item has changed since the last + // time we updated the visibility status. Only then check if the current + // image is a photo sphere. + if (!force && requestId == mLastItemId) { return; } @@ -1273,7 +1279,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { stepIfNeeded(); adjustChildZOrder(); - updateBottomControls(); + updateBottomControls(false /* no forced update */); mLastItemId = getCurrentId(); } @@ -1679,7 +1685,9 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } newItem.copyGeometry(item); mViewItem[itemID] = newItem; - clampCenterX(); + if (clampCenterX()) { + mController.stopScrolling(true); + } } /** Some of the data is changed. */ @@ -1741,8 +1749,10 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } } } - // request a layout to find the measured width/height of the view first. + // Request a layout to find the measured width/height of the view first. requestLayout(); + // Update photo sphere visibility after metadata fully written. + updateBottomControls(true /* forced update */); } /** @@ -1821,16 +1831,17 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { private final ValueAnimator mScaleAnimator; private ValueAnimator mZoomAnimator; - private final Scroller mScroller; + private final MyScroller mScroller; private boolean mCanStopScroll; - private final DecelerateInterpolator mDecelerateInterpolator; private final MyScroller.Listener mScrollerListener = new MyScroller.Listener() { @Override public void onScrollUpdate(int currX, int currY) { mCenterX = currX; - clampCenterX(); + if (clampCenterX()) { + mController.stopScrolling(true); + } invalidate(); } @@ -1862,13 +1873,15 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { }; MyController(Context context) { + TimeInterpolator decelerateInterpolator = new DecelerateInterpolator(1.5f); mScroller = new MyScroller(mActivity, - new Handler(mActivity.getMainLooper()), mScrollerListener); + new Handler(mActivity.getMainLooper()), + mScrollerListener, decelerateInterpolator); mCanStopScroll = true; mScaleAnimator = new ValueAnimator(); mScaleAnimator.addUpdateListener(mScaleAnimatorUpdateListener); - mDecelerateInterpolator = new DecelerateInterpolator(1.5f); + mScaleAnimator.setInterpolator(decelerateInterpolator); } @Override @@ -1965,7 +1978,9 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { return; } mCenterX += deltaX; - clampCenterX(); + if (clampCenterX()) { + mController.stopScrolling(true); + } invalidate(); } @@ -2014,7 +2029,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { @Override public void scrollToPosition(int position, int duration, boolean interruptible) { - if (!stopScrolling(false)) { + if (mViewItem[mCurrentItem] == null) { return; } mCanStopScroll = interruptible; @@ -2045,7 +2060,6 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { stopScale(); mScaleAnimator.setDuration(duration); mScaleAnimator.setFloatValues(mScale, scale); - mScaleAnimator.setInterpolator(mDecelerateInterpolator); mScaleAnimator.start(); } @@ -2165,7 +2179,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } } - private static class MyScroller extends Scroller { + private static class MyScroller { public interface Listener { public void onScrollUpdate(int currX, int currY); public void onScrollEnd(); @@ -2173,46 +2187,98 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { private Handler mHandler; private Listener mListener; + + private final Scroller mScroller; + + private final ValueAnimator mXScrollAnimator; private Runnable mScrollChecker = new Runnable() { @Override public void run() { - boolean newPosition = computeScrollOffset(); + boolean newPosition = mScroller.computeScrollOffset(); if (!newPosition) { mListener.onScrollEnd(); return; } - mListener.onScrollUpdate(getCurrX(), getCurrY()); + mListener.onScrollUpdate(mScroller.getCurrX(), mScroller.getCurrY()); mHandler.removeCallbacks(this); mHandler.post(this); } }; - public MyScroller(Context ctx, Handler handler, Listener listener) { - super(ctx); + private ValueAnimator.AnimatorUpdateListener mXScrollAnimatorUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mListener.onScrollUpdate((Integer) animation.getAnimatedValue(), 0); + } + }; + + private Animator.AnimatorListener mXScrollAnimatorListener = + new Animator.AnimatorListener() { + @Override + public void onAnimationCancel(Animator animation) { + // Do nothing. + } + + @Override + public void onAnimationEnd(Animator animation) { + mListener.onScrollEnd(); + } + + @Override + public void onAnimationRepeat(Animator animation) { + // Do nothing. + } + + @Override + public void onAnimationStart(Animator animation) { + // Do nothing. + } + }; + + + public MyScroller(Context ctx, Handler handler, Listener listener, + TimeInterpolator interpolator) { mHandler = handler; mListener = listener; + mScroller = new Scroller(ctx); + mXScrollAnimator = new ValueAnimator(); + mXScrollAnimator.addUpdateListener(mXScrollAnimatorUpdateListener); + mXScrollAnimator.addListener(mXScrollAnimatorListener); + mXScrollAnimator.setInterpolator(interpolator); } - @Override public void fling( int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) { - super.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY); + mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY); runChecker(); } - @Override public void startScroll(int startX, int startY, int dx, int dy) { - super.startScroll(startX, startY, dx, dy); + mScroller.startScroll(startX, startY, dx, dy); runChecker(); } - @Override + /** Only starts and updates scroll in x-axis. */ public void startScroll(int startX, int startY, int dx, int dy, int duration) { - super.startScroll(startX, startY, dx, dy, duration); - runChecker(); + mXScrollAnimator.cancel(); + mXScrollAnimator.setDuration(duration); + mXScrollAnimator.setIntValues(startX, startX + dx); + mXScrollAnimator.start(); + } + + public boolean isFinished() { + return (mScroller.isFinished() && !mXScrollAnimator.isRunning()); + } + + public void forceFinished(boolean finished) { + mScroller.forceFinished(finished); + if (finished) { + mXScrollAnimator.cancel(); + } } private void runChecker() { |