summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml1
-rw-r--r--res/layout-land/camera_controls.xml3
-rw-r--r--res/layout-port/camera_controls.xml3
-rw-r--r--res/values/strings.xml5
-rw-r--r--src/com/android/camera/CameraActivity.java12
-rw-r--r--src/com/android/camera/ui/FilmStripView.java136
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() {