summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/widget
diff options
context:
space:
mode:
authorPaul Rohde <codelogic@google.com>2015-01-08 18:47:34 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-01-08 18:47:34 +0000
commit10ab1989c2475d137a6db36a4d78d8b68fadf96b (patch)
tree33273d60a9fec5accd1acb5f34a7a9cff03b4ce4 /src/com/android/camera/widget
parente250f88bc01267f03ae3ae192698b0f07c9e425b (diff)
parent8ee16b8a323ffa20e6fb1270d498ec445f64defc (diff)
downloadandroid_packages_apps_Camera2-10ab1989c2475d137a6db36a4d78d8b68fadf96b.tar.gz
android_packages_apps_Camera2-10ab1989c2475d137a6db36a4d78d8b68fadf96b.tar.bz2
android_packages_apps_Camera2-10ab1989c2475d137a6db36a4d78d8b68fadf96b.zip
Merge "Refactor the filmstrip backing data." into ub-camera-haleakala
Diffstat (limited to 'src/com/android/camera/widget')
-rw-r--r--src/com/android/camera/widget/FilmstripLayout.java16
-rw-r--r--src/com/android/camera/widget/FilmstripView.java968
2 files changed, 527 insertions, 457 deletions
diff --git a/src/com/android/camera/widget/FilmstripLayout.java b/src/com/android/camera/widget/FilmstripLayout.java
index 398310050..bbedf240e 100644
--- a/src/com/android/camera/widget/FilmstripLayout.java
+++ b/src/com/android/camera/widget/FilmstripLayout.java
@@ -59,7 +59,7 @@ public class FilmstripLayout extends FrameLayout implements FilmstripContentPane
private FilmstripGestureRecognizer.Listener mFilmstripGestureListener;
private final ValueAnimator mFilmstripAnimator = ValueAnimator.ofFloat(null);
private int mSwipeTrend;
- private MyBackgroundDrawable mBackgroundDrawable;
+ private FilmstripBackground mBackgroundDrawable;
private Handler mHandler;
// We use this to record the current translation position instead of using
// the real value because we might set the translation before onMeasure()
@@ -123,7 +123,7 @@ public class FilmstripLayout extends FrameLayout implements FilmstripContentPane
}
private void init(Context context) {
- mGestureRecognizer = new FilmstripGestureRecognizer(context, new MyGestureListener());
+ mGestureRecognizer = new FilmstripGestureRecognizer(context, new OpenFilmstripGesture());
mFilmstripAnimator.setDuration(DEFAULT_DURATION_MS);
TimeInterpolator interpolator;
if (ApiHelper.isLOrHigher()) {
@@ -136,7 +136,7 @@ public class FilmstripLayout extends FrameLayout implements FilmstripContentPane
mFilmstripAnimator.addUpdateListener(mFilmstripAnimatorUpdateListener);
mFilmstripAnimator.addListener(mFilmstripAnimatorListener);
mHandler = new Handler(Looper.getMainLooper());
- mBackgroundDrawable = new MyBackgroundDrawable();
+ mBackgroundDrawable = new FilmstripBackground();
mBackgroundDrawable.setCallback(new Drawable.Callback() {
@Override
public void invalidateDrawable(Drawable drawable) {
@@ -203,7 +203,7 @@ public class FilmstripLayout extends FrameLayout implements FilmstripContentPane
mListener.onFilmstripShown();
mFilmstripView.zoomAtIndexChanged();
FilmstripController controller = mFilmstripView.getController();
- int currentId = controller.getCurrentId();
+ int currentId = controller.getCurrentAdapterIndex();
if (controller.inFilmstrip()) {
mListener.onEnterFilmstrip(currentId);
} else if (controller.inFullScreen()) {
@@ -323,10 +323,10 @@ public class FilmstripLayout extends FrameLayout implements FilmstripContentPane
* {@code mFilmstripView} by default and only intercepts scroll gestures
* when the {@code mFilmstripView} is not in full-screen.
*/
- private class MyGestureListener implements FilmstripGestureRecognizer.Listener {
+ private class OpenFilmstripGesture implements FilmstripGestureRecognizer.Listener {
@Override
public boolean onScroll(float x, float y, float dx, float dy) {
- if (mFilmstripView.getController().getCurrentId() == -1) {
+ if (mFilmstripView.getController().getCurrentAdapterIndex() == -1) {
return true;
}
if (mFilmstripAnimator.isRunning()) {
@@ -464,11 +464,11 @@ public class FilmstripLayout extends FrameLayout implements FilmstripContentPane
}
}
- private class MyBackgroundDrawable extends Drawable {
+ private class FilmstripBackground extends Drawable {
private Paint mPaint;
private int mOffset;
- public MyBackgroundDrawable() {
+ public FilmstripBackground() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(getResources().getColor(R.color.filmstrip_background));
diff --git a/src/com/android/camera/widget/FilmstripView.java b/src/com/android/camera/widget/FilmstripView.java
index b2529b56d..c213afbec 100644
--- a/src/com/android/camera/widget/FilmstripView.java
+++ b/src/com/android/camera/widget/FilmstripView.java
@@ -21,7 +21,6 @@ import android.animation.AnimatorSet;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
-import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Point;
@@ -43,11 +42,11 @@ import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import com.android.camera.CameraActivity;
-import com.android.camera.data.LocalData.ActionCallback;
+import com.android.camera.data.FilmstripItem;
+import com.android.camera.data.FilmstripItem.VideoClickedCallback;
import com.android.camera.debug.Log;
-import com.android.camera.filmstrip.DataAdapter;
import com.android.camera.filmstrip.FilmstripController;
-import com.android.camera.filmstrip.ImageData;
+import com.android.camera.filmstrip.FilmstripDataAdapter;
import com.android.camera.ui.FilmstripGestureRecognizer;
import com.android.camera.ui.ZoomView;
import com.android.camera.util.ApiHelper;
@@ -63,15 +62,15 @@ public class FilmstripView extends ViewGroup {
/**
* An action callback to be used for actions on the local media data items.
*/
- public static class ActionCallbackImpl implements ActionCallback {
- private final WeakReference<Activity> mActivity;
+ public static class PlayVideoIntent implements VideoClickedCallback {
+ private final WeakReference<CameraActivity> mActivity;
/**
* The given activity is used to start intents. It is wrapped in a weak
* reference to prevent leaks.
*/
- public ActionCallbackImpl(Activity activity) {
- mActivity = new WeakReference<Activity>(activity);
+ public PlayVideoIntent(CameraActivity activity) {
+ mActivity = new WeakReference<CameraActivity>(activity);
}
/**
@@ -79,7 +78,7 @@ public class FilmstripView extends ViewGroup {
*/
@Override
public void playVideo(Uri uri, String title) {
- Activity activity = mActivity.get();
+ CameraActivity activity = mActivity.get();
if (activity != null) {
CameraUtil.playVideo(activity, uri, title);
}
@@ -90,6 +89,7 @@ public class FilmstripView extends ViewGroup {
private static final Log.Tag TAG = new Log.Tag("FilmstripView");
private static final int BUFFER_SIZE = 5;
+ private static final int BUFFER_CENTER = (BUFFER_SIZE - 1) / 2;
private static final int GEOMETRY_ADJUST_TIME_MS = 400;
private static final int SNAP_IN_CENTER_TIME_MS = 600;
private static final float FLING_COASTING_DURATION_S = 0.05f;
@@ -118,18 +118,17 @@ public class FilmstripView extends ViewGroup {
private static final float MOUSE_SCROLL_FACTOR = 128f;
private CameraActivity mActivity;
- private ActionCallback mActionCallback;
+ private VideoClickedCallback mVideoClickedCallback;
private FilmstripGestureRecognizer mGestureRecognizer;
private FilmstripGestureRecognizer.Listener mGestureListener;
- private DataAdapter mDataAdapter;
+ private FilmstripDataAdapter mDataAdapter;
private int mViewGapInPixel;
private final Rect mDrawArea = new Rect();
- private final int mCurrentItem = (BUFFER_SIZE - 1) / 2;
private float mScale;
- private MyController mController;
+ private FilmstripControllerImpl mController;
private int mCenterX = -1;
- private final ViewItem[] mViewItem = new ViewItem[BUFFER_SIZE];
+ private final ViewItem[] mViewItems = new ViewItem[BUFFER_SIZE];
private FilmstripController.FilmstripListener mListener;
private ZoomView mZoomView = null;
@@ -141,44 +140,46 @@ public class FilmstripView extends ViewGroup {
// This is true if and only if the user is scrolling,
private boolean mIsUserScrolling;
- private int mDataIdOnUserScrolling;
+ private int mAdapterIndexUserIsScrollingOver;
private float mOverScaleFactor = 1f;
private boolean mFullScreenUIHidden = false;
- private final SparseArray<Queue<View>> recycledViews = new SparseArray<Queue<View>>();
+ private final SparseArray<Queue<View>> recycledViews = new SparseArray<>();
/**
* A helper class to tract and calculate the view coordination.
*/
- private class ViewItem {
- private int mDataId;
+ private static class ViewItem {
+ private int mIndex;
/** The position of the left of the view in the whole filmstrip. */
private int mLeftPosition;
private final View mView;
- private final ImageData mData;
+ private final FilmstripItem mData;
private final RectF mViewArea;
private boolean mMaximumBitmapRequested;
private ValueAnimator mTranslationXAnimator;
private ValueAnimator mTranslationYAnimator;
private ValueAnimator mAlphaAnimator;
+ private final FilmstripView mFilmstrip;
/**
* Constructor.
*
- * @param id The id of the data from
- * {@link com.android.camera.filmstrip.DataAdapter}.
+ * @param index The index of the data from
+ * {@link com.android.camera.filmstrip.FilmstripDataAdapter}.
* @param v The {@code View} representing the data.
*/
- public ViewItem(int id, View v, ImageData data) {
+ public ViewItem(int index, View v, FilmstripItem data, FilmstripView filmstrip) {
v.setPivotX(0f);
v.setPivotY(0f);
- mDataId = id;
+ mIndex = index;
mData = data;
mView = v;
mMaximumBitmapRequested = false;
mLeftPosition = -1;
mViewArea = new RectF();
+ mFilmstrip = filmstrip;
}
public boolean isMaximumBitmapRequested() {
@@ -190,19 +191,19 @@ public class FilmstripView extends ViewGroup {
}
/**
- * Returns the data id from
- * {@link com.android.camera.filmstrip.DataAdapter}.
+ * Returns the index from
+ * {@link com.android.camera.filmstrip.FilmstripDataAdapter}.
*/
- public int getId() {
- return mDataId;
+ public int getAdapterIndex() {
+ return mIndex;
}
/**
- * Sets the data id from
- * {@link com.android.camera.filmstrip.DataAdapter}.
+ * Sets the index used in the
+ * {@link com.android.camera.filmstrip.FilmstripDataAdapter}.
*/
- public void setId(int id) {
- mDataId = id;
+ public void setIndex(int index) {
+ mIndex = index;
}
/** Sets the left position of the view in the whole filmstrip. */
@@ -217,22 +218,22 @@ public class FilmstripView extends ViewGroup {
/** Returns the translation of Y regarding the view scale. */
public float getTranslationY() {
- return mView.getTranslationY() / mScale;
+ return mView.getTranslationY() / mFilmstrip.mScale;
}
/** Returns the translation of X regarding the view scale. */
public float getTranslationX() {
- return mView.getTranslationX() / mScale;
+ return mView.getTranslationX() / mFilmstrip.mScale;
}
/** Sets the translation of Y regarding the view scale. */
public void setTranslationY(float transY) {
- mView.setTranslationY(transY * mScale);
+ mView.setTranslationY(transY * mFilmstrip.mScale);
}
/** Sets the translation of X regarding the view scale. */
public void setTranslationX(float transX) {
- mView.setTranslationX(transX * mScale);
+ mView.setTranslationX(transX * mFilmstrip.mScale);
}
/** Forwarding of {@link android.view.View#setAlpha(float)}. */
@@ -272,7 +273,7 @@ public class FilmstripView extends ViewGroup {
// translation X because the translation X of the view is
// touched in onLayout(). See the documentation of
// animateTranslationX().
- invalidate();
+ mFilmstrip.invalidate();
}
});
}
@@ -337,7 +338,7 @@ public class FilmstripView extends ViewGroup {
/** Adjusts the translation of X regarding the view scale. */
public void translateXScaledBy(float transX) {
- setTranslationX(getTranslationX() + transX * mScale);
+ setTranslationX(getTranslationX() + transX * mFilmstrip.mScale);
}
/**
@@ -362,20 +363,19 @@ public class FilmstripView extends ViewGroup {
}
/**
- * Notifies the {@link com.android.camera.filmstrip.DataAdapter} to
+ * Notifies the {@link com.android.camera.filmstrip.FilmstripDataAdapter} to
* resize the view.
*/
- public void resizeView(Context context, int w, int h) {
- mDataAdapter.resizeView(context, mDataId, mView, w, h);
+ public void resizeView(int w, int h) {
+ mFilmstrip.mDataAdapter.resizeView(mIndex, mView, w, h);
}
/**
* Adds the view of the data to the view hierarchy if necessary.
*/
public void addViewToHierarchy() {
- if (indexOfChild(mView) < 0) {
- mData.prepare();
- addView(mView);
+ if (mFilmstrip.indexOfChild(mView) < 0) {
+ mFilmstrip.addView(mView);
}
setVisibility(View.VISIBLE);
@@ -392,10 +392,10 @@ public class FilmstripView extends ViewGroup {
* regardless of the view type.
*/
public void removeViewFromHierarchy(boolean force) {
- if (force || mData.getViewType() != ImageData.VIEW_TYPE_STICKY) {
- removeView(mView);
+ if (force || !mData.getAttributes().isSticky()) {
+ mFilmstrip.removeView(mView);
mData.recycle(mView);
- recycleView(mView, mDataId);
+ mFilmstrip.recycleView(mView, mIndex);
} else {
setVisibility(View.INVISIBLE);
}
@@ -406,7 +406,7 @@ public class FilmstripView extends ViewGroup {
* {@link #bringChildToFront(android.view.View)}
*/
public void bringViewToFront() {
- bringChildToFront(mView);
+ mFilmstrip.bringChildToFront(mView);
}
/**
@@ -512,7 +512,7 @@ public class FilmstripView extends ViewGroup {
// translation X because the translation X of the view is
// touched in onLayout(). See the documentation of
// animateTranslationX().
- invalidate();
+ mFilmstrip.invalidate();
}
});
}
@@ -586,7 +586,7 @@ public class FilmstripView extends ViewGroup {
@Override
public String toString() {
- return "DataID = " + mDataId + "\n\t left = " + mLeftPosition
+ return "AdapterIndex = " + mIndex + "\n\t left = " + mLeftPosition
+ "\n\t viewArea = " + mViewArea
+ "\n\t centerX = " + getCenterX()
+ "\n\t view MeasuredSize = "
@@ -617,16 +617,16 @@ public class FilmstripView extends ViewGroup {
private void init(CameraActivity cameraActivity) {
setWillNotDraw(false);
mActivity = cameraActivity;
- mActionCallback = new ActionCallbackImpl(mActivity);
+ mVideoClickedCallback = new PlayVideoIntent(mActivity);
mScale = 1.0f;
- mDataIdOnUserScrolling = 0;
- mController = new MyController(cameraActivity);
+ mAdapterIndexUserIsScrollingOver = 0;
+ mController = new FilmstripControllerImpl();
mViewAnimInterpolator = new DecelerateInterpolator();
mZoomView = new ZoomView(cameraActivity);
mZoomView.setVisibility(GONE);
addView(mZoomView);
- mGestureListener = new MyGestureReceiver();
+ mGestureListener = new FilmstripGestures();
mGestureRecognizer =
new FilmstripGestureRecognizer(cameraActivity, mGestureListener);
mSlop = (int) getContext().getResources().getDimension(R.dimen.pie_touch_slop);
@@ -671,7 +671,7 @@ public class FilmstripView extends ViewGroup {
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: {
// Prevent the view group itself from being selected.
// Instead, select the item in the center
- final ViewItem currentItem = mViewItem[mCurrentItem];
+ final ViewItem currentItem = mViewItems[BUFFER_CENTER];
currentItem.getView().performAccessibilityAction(action, args);
return true;
}
@@ -682,7 +682,7 @@ public class FilmstripView extends ViewGroup {
});
}
- private void recycleView(View view, int dataId) {
+ private void recycleView(View view, int index) {
final int viewType = (Integer) view.getTag(R.id.mediadata_tag_viewtype);
if (viewType > 0) {
Queue<View> recycledViewsForType = recycledViews.get(viewType);
@@ -694,17 +694,17 @@ public class FilmstripView extends ViewGroup {
}
}
- private View getRecycledView(int dataId) {
- final int viewType = mDataAdapter.getItemViewType(dataId);
+ private View getRecycledView(int index) {
+ final int viewType = mDataAdapter.getItemViewType(index);
Queue<View> recycledViewsForType = recycledViews.get(viewType);
- View result = null;
+ View view = null;
if (recycledViewsForType != null) {
- result = recycledViewsForType.poll();
+ view = recycledViewsForType.poll();
}
- if (result != null) {
- result.setVisibility(View.GONE);
+ if (view != null) {
+ view.setVisibility(View.GONE);
}
- return result;
+ return view;
}
/**
@@ -720,7 +720,7 @@ public class FilmstripView extends ViewGroup {
* Returns the draw area width of the current item.
*/
public int getCurrentItemLeft() {
- return mViewItem[mCurrentItem].getDrawAreaLeft();
+ return mViewItems[BUFFER_CENTER].getDrawAreaLeft();
}
private void setListener(FilmstripController.FilmstripListener l) {
@@ -735,24 +735,24 @@ public class FilmstripView extends ViewGroup {
* Called after current item or zoom level has changed.
*/
public void zoomAtIndexChanged() {
- if (mViewItem[mCurrentItem] == null) {
+ if (mViewItems[BUFFER_CENTER] == null) {
return;
}
- int id = mViewItem[mCurrentItem].getId();
- mListener.onZoomAtIndexChanged(id, mScale);
+ int index = mViewItems[BUFFER_CENTER].getAdapterIndex();
+ mListener.onZoomAtIndexChanged(index, mScale);
}
/**
* Checks if the data is at the center.
*
- * @param id The id of the data to check.
+ * @param index The index of the item in the data adapter to check.
* @return {@code True} if the data is currently at the center.
*/
- private boolean isDataAtCenter(int id) {
- if (mViewItem[mCurrentItem] == null) {
+ private boolean isItemAtIndexCentered(int index) {
+ if (mViewItems[BUFFER_CENTER] == null) {
return false;
}
- if (mViewItem[mCurrentItem].getId() == id
+ if (mViewItems[BUFFER_CENTER].getAdapterIndex() == index
&& isCurrentItemCentered()) {
return true;
}
@@ -760,15 +760,19 @@ public class FilmstripView extends ViewGroup {
}
private void measureViewItem(ViewItem item, int boundWidth, int boundHeight) {
- int id = item.getId();
- ImageData imageData = mDataAdapter.getImageData(id);
+ int index = item.getAdapterIndex();
+ FilmstripItem imageData = mDataAdapter.getFilmstripItemAt(index);
if (imageData == null) {
Log.e(TAG, "trying to measure a null item");
return;
}
- Point dim = CameraUtil.resizeToFill(imageData.getWidth(), imageData.getHeight(),
- imageData.getRotation(), boundWidth, boundHeight);
+ Point dim = CameraUtil.resizeToFill(
+ imageData.getData().getDimensions().getWidth(),
+ imageData.getData().getDimensions().getHeight(),
+ imageData.getData().getOrientation(),
+ boundWidth,
+ boundHeight);
item.measure(MeasureSpec.makeMeasureSpec(dim.x, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(dim.y, MeasureSpec.EXACTLY));
@@ -785,7 +789,7 @@ public class FilmstripView extends ViewGroup {
return;
}
- for (ViewItem item : mViewItem) {
+ for (ViewItem item : mViewItems) {
if (item != null) {
measureViewItem(item, boundWidth, boundHeight);
}
@@ -796,12 +800,11 @@ public class FilmstripView extends ViewGroup {
MeasureSpec.makeMeasureSpec(heightMeasureSpec, MeasureSpec.EXACTLY));
}
- private int findTheNearestView(int pointX) {
-
+ private int findTheNearestView(int viewX) {
int nearest = 0;
// Find the first non-null ViewItem.
while (nearest < BUFFER_SIZE
- && (mViewItem[nearest] == null || mViewItem[nearest].getLeftPosition() == -1)) {
+ && (mViewItems[nearest] == null || mViewItems[nearest].getLeftPosition() == -1)) {
nearest++;
}
// No existing available ViewItem
@@ -809,32 +812,32 @@ public class FilmstripView extends ViewGroup {
return -1;
}
- int min = Math.abs(pointX - mViewItem[nearest].getCenterX());
+ int min = Math.abs(viewX - mViewItems[nearest].getCenterX());
- for (int itemID = nearest + 1; itemID < BUFFER_SIZE && mViewItem[itemID] != null; itemID++) {
+ for (int i = nearest + 1; i < BUFFER_SIZE && mViewItems[i] != null; i++) {
// Not measured yet.
- if (mViewItem[itemID].getLeftPosition() == -1) {
+ if (mViewItems[i].getLeftPosition() == -1) {
continue;
}
- int c = mViewItem[itemID].getCenterX();
- int dist = Math.abs(pointX - c);
+ int centerX = mViewItems[i].getCenterX();
+ int dist = Math.abs(viewX - centerX);
if (dist < min) {
min = dist;
- nearest = itemID;
+ nearest = i;
}
}
return nearest;
}
- private ViewItem buildItemFromData(int dataID) {
+ private ViewItem buildViewItemAt(int index) {
if (mActivity.isDestroyed()) {
// Loading item data is call from multiple AsyncTasks and the
- // activity may be finished when buildItemFromData is called.
+ // activity may be finished when buildViewItemAt is called.
Log.d(TAG, "Activity destroyed, don't load data");
return null;
}
- ImageData data = mDataAdapter.getImageData(dataID);
+ FilmstripItem data = mDataAdapter.getFilmstripItemAt(index);
if (data == null) {
return null;
}
@@ -847,47 +850,53 @@ public class FilmstripView extends ViewGroup {
Log.v(TAG, "suggesting item bounds: " + width + "x" + height);
mDataAdapter.suggestViewSizeBound(width, height);
- data.prepare();
- View recycled = getRecycledView(dataID);
- View v = mDataAdapter.getView(mActivity.getAndroidContext(), recycled, dataID,
- mActionCallback);
+ View recycled = getRecycledView(index);
+ View v = mDataAdapter.getView(recycled, index,
+ mVideoClickedCallback);
if (v == null) {
return null;
}
- ViewItem item = new ViewItem(dataID, v, data);
+ ViewItem item = new ViewItem(index, v, data, this);
item.addViewToHierarchy();
return item;
}
- private void checkItemAtMaxSize() {
- ViewItem item = mViewItem[mCurrentItem];
- if (item.isMaximumBitmapRequested()) {
+ private void ensureItemAtMaxSize(int bufferIndex) {
+ ViewItem item = mViewItems[bufferIndex];
+ if (item == null || item.isMaximumBitmapRequested()) {
return;
- };
+ }
item.setMaximumBitmapRequested();
// Request full size bitmap, or max that DataAdapter will create.
- int id = item.getId();
- int h = mDataAdapter.getImageData(id).getHeight();
- int w = mDataAdapter.getImageData(id).getWidth();
- item.resizeView(mActivity, w, h);
+ int index = item.getAdapterIndex();
+ int h = mDataAdapter.getFilmstripItemAt(index).getData().getDimensions().getHeight();
+ int w = mDataAdapter.getFilmstripItemAt(index).getData().getDimensions().getWidth();
+ item.resizeView(w, h);
}
- private void removeItem(int itemID) {
- if (itemID >= mViewItem.length || mViewItem[itemID] == null) {
+ private void ensureBufferItemsAtMaxSize() {
+ for(int i = 0; i < BUFFER_SIZE; i++) {
+ ensureItemAtMaxSize(i);
+ }
+ }
+
+ private void removeItem(int bufferIndex) {
+ if (bufferIndex >= mViewItems.length || mViewItems[bufferIndex] == null) {
return;
}
- ImageData data = mDataAdapter.getImageData(mViewItem[itemID].getId());
+ FilmstripItem data = mDataAdapter.getFilmstripItemAt(
+ mViewItems[bufferIndex].getAdapterIndex());
if (data == null) {
Log.e(TAG, "trying to remove a null item");
return;
}
- mViewItem[itemID].removeViewFromHierarchy(false);
- mViewItem[itemID] = null;
+ mViewItems[bufferIndex].removeViewFromHierarchy(false);
+ mViewItems[bufferIndex] = null;
}
/**
* We try to keep the one closest to the center of the screen at position
- * mCurrentItem.
+ * BUFFER_CENTER.
*/
private void stepIfNeeded() {
if (!inFilmstrip() && !inFullScreen()) {
@@ -895,45 +904,54 @@ public class FilmstripView extends ViewGroup {
// not in transition.
return;
}
- final int nearest = findTheNearestView(mCenterX);
- // no change made.
- if (nearest == -1 || nearest == mCurrentItem) {
+ final int nearestBufferIndex = findTheNearestView(mCenterX);
+ // if the nearest view is the current view, or there is no nearest
+ // view, then we do not need to adjust the view buffers.
+ if (nearestBufferIndex == -1 || nearestBufferIndex == BUFFER_CENTER) {
return;
}
- int prevDataId = (mViewItem[mCurrentItem] == null ? -1 : mViewItem[mCurrentItem].getId());
- final int adjust = nearest - mCurrentItem;
+ int prevIndex = (mViewItems[BUFFER_CENTER] == null ? -1 :
+ mViewItems[BUFFER_CENTER].getAdapterIndex());
+ final int adjust = nearestBufferIndex - BUFFER_CENTER;
if (adjust > 0) {
+ // Remove from beginning of the buffer.
for (int k = 0; k < adjust; k++) {
removeItem(k);
}
+ // Shift items inside the buffer
for (int k = 0; k + adjust < BUFFER_SIZE; k++) {
- mViewItem[k] = mViewItem[k + adjust];
+ mViewItems[k] = mViewItems[k + adjust];
}
+ // Fill the end with new items.
for (int k = BUFFER_SIZE - adjust; k < BUFFER_SIZE; k++) {
- mViewItem[k] = null;
- if (mViewItem[k - 1] != null) {
- mViewItem[k] = buildItemFromData(mViewItem[k - 1].getId() + 1);
+ mViewItems[k] = null;
+ if (mViewItems[k - 1] != null) {
+ mViewItems[k] = buildViewItemAt(mViewItems[k - 1].getAdapterIndex() + 1);
}
}
adjustChildZOrder();
} else {
+ // Remove from the end of the buffer
for (int k = BUFFER_SIZE - 1; k >= BUFFER_SIZE + adjust; k--) {
removeItem(k);
}
+ // Shift items inside the buffer
for (int k = BUFFER_SIZE - 1; k + adjust >= 0; k--) {
- mViewItem[k] = mViewItem[k + adjust];
+ mViewItems[k] = mViewItems[k + adjust];
}
+ // Fill the beginning with new items.
for (int k = -1 - adjust; k >= 0; k--) {
- mViewItem[k] = null;
- if (mViewItem[k + 1] != null) {
- mViewItem[k] = buildItemFromData(mViewItem[k + 1].getId() - 1);
+ mViewItems[k] = null;
+ if (mViewItems[k + 1] != null) {
+ mViewItems[k] = buildViewItemAt(mViewItems[k + 1].getAdapterIndex() - 1);
}
}
}
invalidate();
if (mListener != null) {
- mListener.onDataFocusChanged(prevDataId, mViewItem[mCurrentItem].getId());
- final int firstVisible = mViewItem[mCurrentItem].getId() - 2;
+ mListener.onDataFocusChanged(prevIndex, mViewItems[BUFFER_CENTER]
+ .getAdapterIndex());
+ final int firstVisible = mViewItems[BUFFER_CENTER].getAdapterIndex() - 2;
final int visibleItemCount = firstVisible + BUFFER_SIZE;
final int totalItemCount = mDataAdapter.getTotalNumber();
mListener.onScroll(firstVisible, visibleItemCount, totalItemCount);
@@ -948,45 +966,46 @@ public class FilmstripView extends ViewGroup {
* @return Whether clamp happened.
*/
private boolean clampCenterX() {
- ViewItem curr = mViewItem[mCurrentItem];
- if (curr == null) {
+ ViewItem currentItem = mViewItems[BUFFER_CENTER];
+ if (currentItem == null) {
return false;
}
boolean stopScroll = false;
- if (curr.getId() == 1 && mCenterX < curr.getCenterX() && mDataIdOnUserScrolling > 1 &&
- mDataAdapter.getImageData(0).getViewType() == ImageData.VIEW_TYPE_STICKY &&
+ if (currentItem.getAdapterIndex() == 1 && mCenterX < currentItem.getCenterX()
+ && mAdapterIndexUserIsScrollingOver > 1 &&
+ mDataAdapter.getFilmstripItemAt(0).getAttributes().isSticky() &&
mController.isScrolling()) {
stopScroll = true;
} else {
- if (curr.getId() == 0 && mCenterX < curr.getCenterX()) {
+ if (currentItem.getAdapterIndex() == 0 && mCenterX < currentItem.getCenterX()) {
// Stop at the first ViewItem.
stopScroll = true;
}
}
- if (curr.getId() == mDataAdapter.getTotalNumber() - 1
- && mCenterX > curr.getCenterX()) {
+ if (currentItem.getAdapterIndex() == mDataAdapter.getTotalNumber() - 1
+ && mCenterX > currentItem.getCenterX()) {
// Stop at the end.
stopScroll = true;
}
if (stopScroll) {
- mCenterX = curr.getCenterX();
+ mCenterX = currentItem.getCenterX();
}
return stopScroll;
}
/**
- * Reorders the child views to be consistent with their data ID. This method
+ * Reorders the child views to be consistent with their index. This method
* should be called after adding/removing views.
*/
private void adjustChildZOrder() {
for (int i = BUFFER_SIZE - 1; i >= 0; i--) {
- if (mViewItem[i] == null) {
+ if (mViewItems[i] == null) {
continue;
}
- mViewItem[i].bringViewToFront();
+ mViewItems[i].bringViewToFront();
}
// ZoomView is a special case to always be in the front. In L set to
// max elevation to make sure ZoomView is above other elevated views.
@@ -1002,36 +1021,39 @@ public class FilmstripView extends ViewGroup {
}
/**
- * Returns the ID of the current item, or -1 if there is no data.
+ * Returns the index of the current item, or -1 if there is no data.
*/
- private int getCurrentId() {
- ViewItem current = mViewItem[mCurrentItem];
+ private int getCurrentItemAdapterIndex() {
+ ViewItem current = mViewItems[BUFFER_CENTER];
if (current == null) {
return -1;
}
- return current.getId();
+ return current.getAdapterIndex();
}
/**
* Keep the current item in the center. This functions does not check if the
* current item is null.
*/
- private void snapInCenter() {
- final ViewItem currItem = mViewItem[mCurrentItem];
+ private void scrollCurrentItemToCenter() {
+ final ViewItem currItem = mViewItems[BUFFER_CENTER];
if (currItem == null) {
return;
}
final int currentViewCenter = currItem.getCenterX();
if (mController.isScrolling() || mIsUserScrolling
|| isCurrentItemCentered()) {
+ Log.e(TAG, "[fling] = mController.isScrolling() " + mController.isScrolling());
return;
}
int snapInTime = (int) (SNAP_IN_CENTER_TIME_MS
* ((float) Math.abs(mCenterX - currentViewCenter))
/ mDrawArea.width());
+
+ Log.e(TAG, "[fling] Scroll to center.");
mController.scrollToPosition(currentViewCenter,
- snapInTime, false);
+ snapInTime, false);
if (isViewTypeSticky(currItem) && !mController.isScaling() && mScale != FULL_SCREEN_SCALE) {
// Now going to full screen camera
mController.goToFullScreen();
@@ -1044,24 +1066,24 @@ public class FilmstripView extends ViewGroup {
* which occupies the whole screen. The other left ones are put on the left
* side in full scales. Does nothing if there's no next item.
*
- * @param currItem The item ID of the current one to be translated.
+ * @param index The index of the current one to be translated.
* @param drawAreaWidth The width of the current draw area.
* @param scaleFraction A {@code float} between 0 and 1. 0 if the current
* scale is {@code FILM_STRIP_SCALE}. 1 if the current scale is
* {@code FULL_SCREEN_SCALE}.
*/
private void translateLeftViewItem(
- int currItem, int drawAreaWidth, float scaleFraction) {
- if (currItem < 0 || currItem > BUFFER_SIZE - 1) {
- Log.e(TAG, "currItem id out of bound.");
+ int index, int drawAreaWidth, float scaleFraction) {
+ if (index < 0 || index > BUFFER_SIZE - 1) {
+ Log.e(TAG, "index out of bound.");
return;
}
- final ViewItem curr = mViewItem[currItem];
- final ViewItem next = mViewItem[currItem + 1];
+ final ViewItem curr = mViewItems[index];
+ final ViewItem next = mViewItems[index + 1];
if (curr == null || next == null) {
Log.e(TAG, "Invalid view item (curr or next == null). curr = "
- + currItem);
+ + index);
return;
}
@@ -1075,7 +1097,8 @@ public class FilmstripView extends ViewGroup {
curr.setVisibility(VISIBLE);
if (inFullScreen()) {
- curr.setTranslationX(translate * (mCenterX - currCenterX) / (nextCenterX - currCenterX));
+ curr.setTranslationX(translate * (mCenterX - currCenterX) /
+ (nextCenterX - currCenterX));
} else {
curr.setTranslationX(translate);
}
@@ -1085,46 +1108,46 @@ public class FilmstripView extends ViewGroup {
* Fade out the {@link ViewItem} on the right of the current one in
* full-screen layout. Does nothing if there's no previous item.
*
- * @param currItemId The ID of the item to fade.
+ * @param bufferIndex The index of the item in the buffer to fade.
*/
- private void fadeAndScaleRightViewItem(int currItemId) {
- if (currItemId < 1 || currItemId > BUFFER_SIZE) {
- Log.e(TAG, "currItem id out of bound.");
+ private void fadeAndScaleRightViewItem(int bufferIndex) {
+ if (bufferIndex < 1 || bufferIndex > BUFFER_SIZE) {
+ Log.e(TAG, "index id out of bound.");
return;
}
- final ViewItem currItem = mViewItem[currItemId];
- final ViewItem prevItem = mViewItem[currItemId - 1];
- if (currItem == null || prevItem == null) {
+ final ViewItem item = mViewItems[bufferIndex];
+ final ViewItem previousItem = mViewItems[bufferIndex - 1];
+ if (item == null || previousItem == null) {
Log.e(TAG, "Invalid view item (curr or prev == null). curr = "
- + currItemId);
+ + bufferIndex);
return;
}
- if (currItemId > mCurrentItem + 1) {
- // Every item not right next to the mCurrentItem is invisible.
- currItem.setVisibility(INVISIBLE);
+ if (bufferIndex > BUFFER_CENTER + 1) {
+ // Every item not right next to the BUFFER_CENTER is invisible.
+ item.setVisibility(INVISIBLE);
return;
}
- final int prevCenterX = prevItem.getCenterX();
+ final int prevCenterX = previousItem.getCenterX();
if (mCenterX <= prevCenterX) {
// Shortcut. If the position is at the center of the previous one,
// set to invisible too.
- currItem.setVisibility(INVISIBLE);
+ item.setVisibility(INVISIBLE);
return;
}
- final int currCenterX = currItem.getCenterX();
+ final int currCenterX = item.getCenterX();
final float fadeDownFraction =
((float) mCenterX - prevCenterX) / (currCenterX - prevCenterX);
- currItem.layoutWithTranslationX(mDrawArea, currCenterX,
- FILM_STRIP_SCALE + (1f - FILM_STRIP_SCALE) * fadeDownFraction);
- currItem.setAlpha(fadeDownFraction);
- currItem.setTranslationX(0);
- currItem.setVisibility(VISIBLE);
+ item.layoutWithTranslationX(mDrawArea, currCenterX,
+ FILM_STRIP_SCALE + (1f - FILM_STRIP_SCALE) * fadeDownFraction);
+ item.setAlpha(fadeDownFraction);
+ item.setTranslationX(0);
+ item.setVisibility(VISIBLE);
}
private void layoutViewItems(boolean layoutChanged) {
- if (mViewItem[mCurrentItem] == null ||
+ if (mViewItems[BUFFER_CENTER] == null ||
mDrawArea.width() == 0 ||
mDrawArea.height() == 0) {
return;
@@ -1133,8 +1156,8 @@ public class FilmstripView extends ViewGroup {
// If the layout changed, we need to adjust the current position so
// that if an item is centered before the change, it's still centered.
if (layoutChanged) {
- mViewItem[mCurrentItem].setLeftPosition(
- mCenterX - mViewItem[mCurrentItem].getMeasuredWidth() / 2);
+ mViewItems[BUFFER_CENTER].setLeftPosition(
+ mCenterX - mViewItems[BUFFER_CENTER].getMeasuredWidth() / 2);
}
if (inZoomView()) {
@@ -1153,26 +1176,26 @@ public class FilmstripView extends ViewGroup {
// first.
// Left items.
- for (int itemID = mCurrentItem - 1; itemID >= 0; itemID--) {
- final ViewItem curr = mViewItem[itemID];
+ for (int i = BUFFER_CENTER - 1; i >= 0; i--) {
+ final ViewItem curr = mViewItems[i];
if (curr == null) {
break;
}
// First, layout relatively to the next one.
- final int currLeft = mViewItem[itemID + 1].getLeftPosition()
+ final int currLeft = mViewItems[i + 1].getLeftPosition()
- curr.getMeasuredWidth() - mViewGapInPixel;
curr.setLeftPosition(currLeft);
}
// Right items.
- for (int itemID = mCurrentItem + 1; itemID < BUFFER_SIZE; itemID++) {
- final ViewItem curr = mViewItem[itemID];
+ for (int i = BUFFER_CENTER + 1; i < BUFFER_SIZE; i++) {
+ final ViewItem curr = mViewItems[i];
if (curr == null) {
break;
}
// First, layout relatively to the previous one.
- final ViewItem prev = mViewItem[itemID - 1];
+ final ViewItem prev = mViewItems[i - 1];
final int currLeft =
prev.getLeftPosition() + prev.getMeasuredWidth()
+ mViewGapInPixel;
@@ -1182,8 +1205,8 @@ public class FilmstripView extends ViewGroup {
// Special case for the one immediately on the right of the camera
// preview.
boolean immediateRight =
- (mViewItem[mCurrentItem].getId() == 1 &&
- mDataAdapter.getImageData(0).getViewType() == ImageData.VIEW_TYPE_STICKY);
+ (mViewItems[BUFFER_CENTER].getAdapterIndex() == 1 &&
+ mDataAdapter.getFilmstripItemAt(0).getAttributes().isSticky());
// Layout the current ViewItem first.
if (immediateRight) {
@@ -1191,37 +1214,37 @@ public class FilmstripView extends ViewGroup {
// fading. The implementation in Gallery does not push the first
// photo to the bottom of the camera preview. Simply place the
// photo on the right of the preview.
- final ViewItem currItem = mViewItem[mCurrentItem];
+ final ViewItem currItem = mViewItems[BUFFER_CENTER];
currItem.layoutWithTranslationX(mDrawArea, mCenterX, mScale);
currItem.setTranslationX(0f);
currItem.setAlpha(1f);
} else if (scaleFraction == 1f) {
- final ViewItem currItem = mViewItem[mCurrentItem];
+ final ViewItem currItem = mViewItems[BUFFER_CENTER];
final int currCenterX = currItem.getCenterX();
if (mCenterX < currCenterX) {
// In full-screen and mCenterX is on the left of the center,
// we draw the current one to "fade down".
- fadeAndScaleRightViewItem(mCurrentItem);
+ fadeAndScaleRightViewItem(BUFFER_CENTER);
} else if (mCenterX > currCenterX) {
// In full-screen and mCenterX is on the right of the center,
// we draw the current one translated.
- translateLeftViewItem(mCurrentItem, fullScreenWidth, scaleFraction);
+ translateLeftViewItem(BUFFER_CENTER, fullScreenWidth, scaleFraction);
} else {
currItem.layoutWithTranslationX(mDrawArea, mCenterX, mScale);
currItem.setTranslationX(0f);
currItem.setAlpha(1f);
}
} else {
- final ViewItem currItem = mViewItem[mCurrentItem];
+ final ViewItem currItem = mViewItems[BUFFER_CENTER];
// The normal filmstrip has no translation for the current item. If
// it has translation before, gradually set it to zero.
currItem.setTranslationX(currItem.getTranslationX() * scaleFraction);
currItem.layoutWithTranslationX(mDrawArea, mCenterX, mScale);
- if (mViewItem[mCurrentItem - 1] == null) {
+ if (mViewItems[BUFFER_CENTER - 1] == null) {
currItem.setAlpha(1f);
} else {
final int currCenterX = currItem.getCenterX();
- final int prevCenterX = mViewItem[mCurrentItem - 1].getCenterX();
+ final int prevCenterX = mViewItems[BUFFER_CENTER - 1].getCenterX();
final float fadeDownFraction =
((float) mCenterX - prevCenterX) / (currCenterX - prevCenterX);
currItem.setAlpha(
@@ -1232,23 +1255,23 @@ public class FilmstripView extends ViewGroup {
// Layout the rest dependent on the current scale.
// Items on the left
- for (int itemID = mCurrentItem - 1; itemID >= 0; itemID--) {
- final ViewItem curr = mViewItem[itemID];
+ for (int i = BUFFER_CENTER - 1; i >= 0; i--) {
+ final ViewItem curr = mViewItems[i];
if (curr == null) {
break;
}
- translateLeftViewItem(itemID, fullScreenWidth, scaleFraction);
+ translateLeftViewItem(i, fullScreenWidth, scaleFraction);
}
// Items on the right
- for (int itemID = mCurrentItem + 1; itemID < BUFFER_SIZE; itemID++) {
- final ViewItem curr = mViewItem[itemID];
+ for (int i = BUFFER_CENTER + 1; i < BUFFER_SIZE; i++) {
+ final ViewItem curr = mViewItems[i];
if (curr == null) {
break;
}
curr.layoutWithTranslationX(mDrawArea, mCenterX, mScale);
- if (curr.getId() == 1 && isViewTypeSticky(curr)) {
+ if (curr.getAdapterIndex() == 1 && isViewTypeSticky(curr)) {
// Special case for the one next to the camera preview.
curr.setAlpha(1f);
continue;
@@ -1256,11 +1279,11 @@ public class FilmstripView extends ViewGroup {
if (scaleFraction == 1) {
// It's in full-screen mode.
- fadeAndScaleRightViewItem(itemID);
+ fadeAndScaleRightViewItem(i);
} else {
boolean setToVisible = (curr.getVisibility() == INVISIBLE);
- if (itemID == mCurrentItem + 1) {
+ if (i == BUFFER_CENTER + 1) {
curr.setAlpha(1f - scaleFraction);
} else {
if (scaleFraction == 0f) {
@@ -1274,9 +1297,8 @@ public class FilmstripView extends ViewGroup {
curr.setVisibility(VISIBLE);
}
- curr.setTranslationX(
- (mViewItem[mCurrentItem].getLeftPosition() - curr.getLeftPosition()) *
- scaleFraction);
+ curr.setTranslationX((mViewItems[BUFFER_CENTER].getLeftPosition() -
+ curr.getLeftPosition()) * scaleFraction);
}
}
@@ -1287,8 +1309,7 @@ public class FilmstripView extends ViewGroup {
if (item == null) {
return false;
}
- return mDataAdapter.getImageData(item.getId()).getViewType() ==
- ImageData.VIEW_TYPE_STICKY;
+ return mDataAdapter.getFilmstripItemAt(item.getAdapterIndex()).getAttributes().isSticky();
}
@Override
@@ -1324,7 +1345,7 @@ public class FilmstripView extends ViewGroup {
if (!inZoomView()) {
return;
}
- ViewItem current = mViewItem[mCurrentItem];
+ ViewItem current = mViewItems[BUFFER_CENTER];
if (current == null) {
return;
}
@@ -1350,75 +1371,75 @@ public class FilmstripView extends ViewGroup {
item.animateAlpha(1f, GEOMETRY_ADJUST_TIME_MS, mViewAnimInterpolator);
}
- private void animateItemRemoval(int dataID, final ImageData data) {
+ private void animateItemRemoval(int index) {
if (mScale > FULL_SCREEN_SCALE) {
resetZoomView();
}
- int removedItemId = findItemByDataID(dataID);
+ int removeAtBufferIndex = findItemInBufferByAdapterIndex(index);
- // adjust the data id to be consistent
+ // adjust the buffer to be consistent
for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewItem[i] == null || mViewItem[i].getId() <= dataID) {
+ if (mViewItems[i] == null || mViewItems[i].getAdapterIndex() <= index) {
continue;
}
- mViewItem[i].setId(mViewItem[i].getId() - 1);
+ mViewItems[i].setIndex(mViewItems[i].getAdapterIndex() - 1);
}
- if (removedItemId == -1) {
+ if (removeAtBufferIndex == -1) {
return;
}
- final ViewItem removedItem = mViewItem[removedItemId];
+ final ViewItem removedItem = mViewItems[removeAtBufferIndex];
final int offsetX = removedItem.getMeasuredWidth() + mViewGapInPixel;
- for (int i = removedItemId + 1; i < BUFFER_SIZE; i++) {
- if (mViewItem[i] != null) {
- mViewItem[i].setLeftPosition(mViewItem[i].getLeftPosition() - offsetX);
+ for (int i = removeAtBufferIndex + 1; i < BUFFER_SIZE; i++) {
+ if (mViewItems[i] != null) {
+ mViewItems[i].setLeftPosition(mViewItems[i].getLeftPosition() - offsetX);
}
}
- if (removedItemId >= mCurrentItem
- && mViewItem[removedItemId].getId() < mDataAdapter.getTotalNumber()) {
+ if (removeAtBufferIndex >= BUFFER_CENTER
+ && mViewItems[removeAtBufferIndex].getAdapterIndex() < mDataAdapter.getTotalNumber()) {
// Fill the removed item by left shift when the current one or
// anyone on the right is removed, and there's more data on the
// right available.
- for (int i = removedItemId; i < BUFFER_SIZE - 1; i++) {
- mViewItem[i] = mViewItem[i + 1];
+ for (int i = removeAtBufferIndex; i < BUFFER_SIZE - 1; i++) {
+ mViewItems[i] = mViewItems[i + 1];
}
// pull data out from the DataAdapter for the last one.
int curr = BUFFER_SIZE - 1;
int prev = curr - 1;
- if (mViewItem[prev] != null) {
- mViewItem[curr] = buildItemFromData(mViewItem[prev].getId() + 1);
+ if (mViewItems[prev] != null) {
+ mViewItems[curr] = buildViewItemAt(mViewItems[prev].getAdapterIndex() + 1);
}
// The animation part.
if (inFullScreen()) {
- mViewItem[mCurrentItem].setVisibility(VISIBLE);
- ViewItem nextItem = mViewItem[mCurrentItem + 1];
+ mViewItems[BUFFER_CENTER].setVisibility(VISIBLE);
+ ViewItem nextItem = mViewItems[BUFFER_CENTER + 1];
if (nextItem != null) {
nextItem.setVisibility(INVISIBLE);
}
}
// Translate the views to their original places.
- for (int i = removedItemId; i < BUFFER_SIZE; i++) {
- if (mViewItem[i] != null) {
- mViewItem[i].setTranslationX(offsetX);
+ for (int i = removeAtBufferIndex; i < BUFFER_SIZE; i++) {
+ if (mViewItems[i] != null) {
+ mViewItems[i].setTranslationX(offsetX);
}
}
// The end of the filmstrip might have been changed.
// The mCenterX might be out of the bound.
- ViewItem currItem = mViewItem[mCurrentItem];
- if(currItem!=null) {
- if (currItem.getId() == mDataAdapter.getTotalNumber() - 1
+ ViewItem currItem = mViewItems[BUFFER_CENTER];
+ if (currItem!=null) {
+ if (currItem.getAdapterIndex() == mDataAdapter.getTotalNumber() - 1
&& mCenterX > currItem.getCenterX()) {
int adjustDiff = currItem.getCenterX() - mCenterX;
mCenterX = currItem.getCenterX();
for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewItem[i] != null) {
- mViewItem[i].translateXScaledBy(adjustDiff);
+ if (mViewItems[i] != null) {
+ mViewItems[i].translateXScaledBy(adjustDiff);
}
}
}
@@ -1430,21 +1451,22 @@ public class FilmstripView extends ViewGroup {
// fill the removed place by right shift
mCenterX -= offsetX;
- for (int i = removedItemId; i > 0; i--) {
- mViewItem[i] = mViewItem[i - 1];
+ for (int i = removeAtBufferIndex; i > 0; i--) {
+ mViewItems[i] = mViewItems[i - 1];
}
// pull data out from the DataAdapter for the first one.
int curr = 0;
int next = curr + 1;
- if (mViewItem[next] != null) {
- mViewItem[curr] = buildItemFromData(mViewItem[next].getId() - 1);
+ if (mViewItems[next] != null) {
+ mViewItems[curr] = buildViewItemAt(mViewItems[next].getAdapterIndex() - 1);
+
}
// Translate the views to their original places.
- for (int i = removedItemId; i >= 0; i--) {
- if (mViewItem[i] != null) {
- mViewItem[i].setTranslationX(-offsetX);
+ for (int i = removeAtBufferIndex; i >= 0; i--) {
+ if (mViewItems[i] != null) {
+ mViewItems[i].setTranslationX(-offsetX);
}
}
}
@@ -1467,100 +1489,105 @@ public class FilmstripView extends ViewGroup {
invalidate();
// Now, slide every one back.
- if (mViewItem[mCurrentItem] == null) {
+ if (mViewItems[BUFFER_CENTER] == null) {
return;
}
for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewItem[i] != null
- && mViewItem[i].getTranslationX() != 0f) {
- slideViewBack(mViewItem[i]);
+ if (mViewItems[i] != null
+ && mViewItems[i].getTranslationX() != 0f) {
+ slideViewBack(mViewItems[i]);
}
}
- if (isCurrentItemCentered() && isViewTypeSticky(mViewItem[mCurrentItem])) {
+ if (isCurrentItemCentered() && isViewTypeSticky(mViewItems[BUFFER_CENTER])) {
// Special case for scrolling onto the camera preview after removal.
mController.goToFullScreen();
}
}
// returns -1 on failure.
- private int findItemByDataID(int dataID) {
+ private int findItemInBufferByAdapterIndex(int index) {
for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewItem[i] != null
- && mViewItem[i].getId() == dataID) {
+ if (mViewItems[i] != null
+ && mViewItems[i].getAdapterIndex() == index) {
return i;
}
}
return -1;
}
- private void updateInsertion(int dataID) {
- int insertedItemId = findItemByDataID(dataID);
- if (insertedItemId == -1) {
+ private void updateInsertion(int index) {
+ int bufferIndex = findItemInBufferByAdapterIndex(index);
+ if (bufferIndex == -1) {
// Not in the current item buffers. Check if it's inserted
// at the end.
- if (dataID == mDataAdapter.getTotalNumber() - 1) {
- int prev = findItemByDataID(dataID - 1);
+ if (index == mDataAdapter.getTotalNumber() - 1) {
+ int prev = findItemInBufferByAdapterIndex(index - 1);
if (prev >= 0 && prev < BUFFER_SIZE - 1) {
// The previous data is in the buffer and we still
// have room for the inserted data.
- insertedItemId = prev + 1;
+ bufferIndex = prev + 1;
}
}
}
- // adjust the data id to be consistent
+ // adjust the indexes to be consistent
for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewItem[i] == null || mViewItem[i].getId() < dataID) {
+ if (mViewItems[i] == null || mViewItems[i].getAdapterIndex() < index) {
continue;
}
- mViewItem[i].setId(mViewItem[i].getId() + 1);
+ mViewItems[i].setIndex(mViewItems[i].getAdapterIndex() + 1);
}
- if (insertedItemId == -1) {
+ if (bufferIndex == -1) {
return;
}
- final ImageData data = mDataAdapter.getImageData(dataID);
+ final FilmstripItem data = mDataAdapter.getFilmstripItemAt(index);
Point dim = CameraUtil
- .resizeToFill(data.getWidth(), data.getHeight(), data.getRotation(),
- getMeasuredWidth(), getMeasuredHeight());
+ .resizeToFill(
+ data.getData().getDimensions().getWidth(),
+ data.getData().getDimensions().getHeight(),
+ data.getData().getOrientation(),
+ getMeasuredWidth(),
+ getMeasuredHeight());
final int offsetX = dim.x + mViewGapInPixel;
- ViewItem viewItem = buildItemFromData(dataID);
+ ViewItem viewItem = buildViewItemAt(index);
if (viewItem == null) {
Log.w(TAG, "unable to build inserted item from data");
return;
}
- if (insertedItemId >= mCurrentItem) {
- if (insertedItemId == mCurrentItem) {
- viewItem.setLeftPosition(mViewItem[mCurrentItem].getLeftPosition());
+ // TODO: Ensure newly visible items are loaded at full size.
+ if (bufferIndex >= BUFFER_CENTER) {
+ if (bufferIndex == BUFFER_CENTER) {
+ viewItem.setLeftPosition(mViewItems[BUFFER_CENTER].getLeftPosition());
}
// Shift right to make rooms for newly inserted item.
removeItem(BUFFER_SIZE - 1);
- for (int i = BUFFER_SIZE - 1; i > insertedItemId; i--) {
- mViewItem[i] = mViewItem[i - 1];
- if (mViewItem[i] != null) {
- mViewItem[i].setTranslationX(-offsetX);
- slideViewBack(mViewItem[i]);
+ for (int i = BUFFER_SIZE - 1; i > bufferIndex; i--) {
+ mViewItems[i] = mViewItems[i - 1];
+ if (mViewItems[i] != null) {
+ mViewItems[i].setTranslationX(-offsetX);
+ slideViewBack(mViewItems[i]);
}
}
} else {
// Shift left. Put the inserted data on the left instead of the
// found position.
- --insertedItemId;
- if (insertedItemId < 0) {
+ --bufferIndex;
+ if (bufferIndex < 0) {
return;
}
removeItem(0);
- for (int i = 1; i <= insertedItemId; i++) {
- if (mViewItem[i] != null) {
- mViewItem[i].setTranslationX(offsetX);
- slideViewBack(mViewItem[i]);
- mViewItem[i - 1] = mViewItem[i];
+ for (int i = 1; i <= bufferIndex; i++) {
+ if (mViewItems[i] != null) {
+ mViewItems[i].setTranslationX(offsetX);
+ slideViewBack(mViewItems[i]);
+ mViewItems[i - 1] = mViewItems[i];
}
}
}
- mViewItem[insertedItemId] = viewItem;
+ mViewItems[bufferIndex] = viewItem;
viewItem.setAlpha(0f);
viewItem.setTranslationY(getHeight() / 8);
slideViewBack(viewItem);
@@ -1568,41 +1595,47 @@ public class FilmstripView extends ViewGroup {
invalidate();
}
- private void setDataAdapter(DataAdapter adapter) {
+ private void setDataAdapter(FilmstripDataAdapter adapter) {
mDataAdapter = adapter;
int maxEdge = (int) (Math.max(this.getHeight(), this.getWidth())
* FILM_STRIP_SCALE);
mDataAdapter.suggestViewSizeBound(maxEdge, maxEdge);
- mDataAdapter.setListener(new DataAdapter.Listener() {
+ mDataAdapter.setListener(new FilmstripDataAdapter.Listener() {
@Override
- public void onDataLoaded() {
+ public void onFilmstripItemLoaded() {
reload();
}
@Override
- public void onDataUpdated(DataAdapter.UpdateReporter reporter) {
+ public void onFilmstripItemUpdated(FilmstripDataAdapter.UpdateReporter reporter) {
update(reporter);
}
@Override
- public void onDataInserted(int dataId, ImageData data) {
- if (mViewItem[mCurrentItem] == null) {
+ public void onFilmstripItemInserted(int index, FilmstripItem item) {
+ if (mViewItems[BUFFER_CENTER] == null) {
// empty now, simply do a reload.
reload();
} else {
- updateInsertion(dataId);
+ updateInsertion(index);
}
if (mListener != null) {
- mListener.onDataFocusChanged(dataId, getCurrentId());
+ mListener.onDataFocusChanged(index, getCurrentItemAdapterIndex());
}
+ Log.d(TAG, "[ensureItemAtMaxSize] [ensureBufferItemsAtMaxSize]"
+ + " onFilmstripItemInserted()");
+ ensureBufferItemsAtMaxSize();
}
@Override
- public void onDataRemoved(int dataId, ImageData data) {
- animateItemRemoval(dataId, data);
+ public void onFilmstripItemRemoved(int index, FilmstripItem item) {
+ animateItemRemoval(index);
if (mListener != null) {
- mListener.onDataFocusChanged(dataId, getCurrentId());
+ mListener.onDataFocusChanged(index, getCurrentItemAdapterIndex());
}
+ Log.d(TAG, "[ensureItemAtMaxSize] [ensureBufferItemsAtMaxSize]"
+ + " onFilmstripItemRemoved()");
+ ensureBufferItemsAtMaxSize();
}
});
}
@@ -1620,12 +1653,12 @@ public class FilmstripView extends ViewGroup {
}
private boolean isCameraPreview() {
- return isViewTypeSticky(mViewItem[mCurrentItem]);
+ return isViewTypeSticky(mViewItems[BUFFER_CENTER]);
}
private boolean inCameraFullscreen() {
- return isDataAtCenter(0) && inFullScreen()
- && (isViewTypeSticky(mViewItem[mCurrentItem]));
+ return isItemAtIndexCentered(0) && inFullScreen()
+ && (isViewTypeSticky(mViewItems[BUFFER_CENTER]));
}
@Override
@@ -1637,9 +1670,10 @@ public class FilmstripView extends ViewGroup {
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
mCheckToIntercept = true;
mDown = MotionEvent.obtain(ev);
- ViewItem viewItem = mViewItem[mCurrentItem];
+ ViewItem viewItem = mViewItems[BUFFER_CENTER];
// Do not intercept touch if swipe is not enabled
- if (viewItem != null && !mDataAdapter.canSwipeInFullScreen(viewItem.getId())) {
+ if (viewItem != null &&
+ !mDataAdapter.canSwipeInFullScreen(viewItem.getAdapterIndex())) {
mCheckToIntercept = false;
}
return false;
@@ -1682,15 +1716,15 @@ public class FilmstripView extends ViewGroup {
return mGestureListener;
}
- private void updateViewItem(int itemID) {
- ViewItem item = mViewItem[itemID];
+ private void updateViewItem(int bufferIndex) {
+ ViewItem item = mViewItems[bufferIndex];
if (item == null) {
Log.e(TAG, "trying to update an null item");
return;
}
item.removeViewFromHierarchy(true);
- ViewItem newItem = buildItemFromData(item.getId());
+ ViewItem newItem = buildViewItemAt(item.getAdapterIndex());
if (newItem == null) {
Log.e(TAG, "new item is null");
// keep using the old data.
@@ -1698,82 +1732,89 @@ public class FilmstripView extends ViewGroup {
return;
}
newItem.copyAttributes(item);
- mViewItem[itemID] = newItem;
+ mViewItems[bufferIndex] = newItem;
mZoomView.resetDecoder();
boolean stopScroll = clampCenterX();
if (stopScroll) {
mController.stopScrolling(true);
}
+
+ Log.d(TAG, "[ensureItemAtMaxSize] updateViewItem()");
+
adjustChildZOrder();
invalidate();
if (mListener != null) {
- mListener.onDataUpdated(newItem.getId());
+ mListener.onDataUpdated(newItem.getAdapterIndex());
}
}
/** Some of the data is changed. */
- private void update(DataAdapter.UpdateReporter reporter) {
+ private void update(FilmstripDataAdapter.UpdateReporter reporter) {
// No data yet.
- if (mViewItem[mCurrentItem] == null) {
+ if (mViewItems[BUFFER_CENTER] == null) {
reload();
return;
}
// Check the current one.
- ViewItem curr = mViewItem[mCurrentItem];
- int dataId = curr.getId();
- if (reporter.isDataRemoved(dataId)) {
+ ViewItem curr = mViewItems[BUFFER_CENTER];
+ int index = curr.getAdapterIndex();
+ if (reporter.isDataRemoved(index)) {
reload();
return;
}
- if (reporter.isDataUpdated(dataId)) {
- updateViewItem(mCurrentItem);
- final ImageData data = mDataAdapter.getImageData(dataId);
+ if (reporter.isDataUpdated(index)) {
+ updateViewItem(BUFFER_CENTER);
+ final FilmstripItem data = mDataAdapter.getFilmstripItemAt(index);
if (!mIsUserScrolling && !mController.isScrolling()) {
// If there is no scrolling at all, adjust mCenterX to place
// the current item at the center.
- Point dim = CameraUtil.resizeToFill(data.getWidth(), data.getHeight(),
- data.getRotation(), getMeasuredWidth(), getMeasuredHeight());
+ Point dim = CameraUtil.resizeToFill(
+ data.getData().getDimensions().getWidth(),
+ data.getData().getDimensions().getHeight(),
+ data.getData().getOrientation(),
+ getMeasuredWidth(),
+ getMeasuredHeight());
mCenterX = curr.getLeftPosition() + dim.x / 2;
}
}
// Check left
- for (int i = mCurrentItem - 1; i >= 0; i--) {
- curr = mViewItem[i];
+ for (int i = BUFFER_CENTER - 1; i >= 0; i--) {
+ curr = mViewItems[i];
if (curr != null) {
- dataId = curr.getId();
- if (reporter.isDataRemoved(dataId) || reporter.isDataUpdated(dataId)) {
+ index = curr.getAdapterIndex();
+ if (reporter.isDataRemoved(index) || reporter.isDataUpdated(index)) {
updateViewItem(i);
}
+
} else {
- ViewItem next = mViewItem[i + 1];
+ ViewItem next = mViewItems[i + 1];
if (next != null) {
- mViewItem[i] = buildItemFromData(next.getId() - 1);
+ mViewItems[i] = buildViewItemAt(next.getAdapterIndex() - 1);
}
}
}
// Check right
- for (int i = mCurrentItem + 1; i < BUFFER_SIZE; i++) {
- curr = mViewItem[i];
+ for (int i = BUFFER_CENTER + 1; i < BUFFER_SIZE; i++) {
+ curr = mViewItems[i];
if (curr != null) {
- dataId = curr.getId();
- if (reporter.isDataRemoved(dataId) || reporter.isDataUpdated(dataId)) {
+ index = curr.getAdapterIndex();
+ if (reporter.isDataRemoved(index) || reporter.isDataUpdated(index)) {
updateViewItem(i);
}
} else {
- ViewItem prev = mViewItem[i - 1];
+ ViewItem prev = mViewItems[i - 1];
if (prev != null) {
- mViewItem[i] = buildItemFromData(prev.getId() + 1);
+ mViewItems[i] = buildViewItemAt(prev.getAdapterIndex() + 1);
}
}
}
adjustChildZOrder();
// Request a layout to find the measured width/height of the view first.
requestLayout();
- // Update photo sphere visibility after metadata fully written.
}
/**
@@ -1784,108 +1825,111 @@ public class FilmstripView extends ViewGroup {
private void reload() {
mController.stopScrolling(true);
mController.stopScale();
- mDataIdOnUserScrolling = 0;
+ mAdapterIndexUserIsScrollingOver = 0;
int prevId = -1;
- if (mViewItem[mCurrentItem] != null) {
- prevId = mViewItem[mCurrentItem].getId();
+ if (mViewItems[BUFFER_CENTER] != null) {
+ prevId = mViewItems[BUFFER_CENTER].getAdapterIndex();
}
- // Remove all views from the mViewItem buffer, except the camera view.
- for (int i = 0; i < mViewItem.length; i++) {
- if (mViewItem[i] == null) {
+ // Remove all views from the mViewItems buffer, except the camera view.
+ for (int i = 0; i < mViewItems.length; i++) {
+ if (mViewItems[i] == null) {
continue;
}
- mViewItem[i].removeViewFromHierarchy(false);
+ mViewItems[i].removeViewFromHierarchy(false);
}
// Clear out the mViewItems and rebuild with camera in the center.
- Arrays.fill(mViewItem, null);
+ Arrays.fill(mViewItems, null);
int dataNumber = mDataAdapter.getTotalNumber();
if (dataNumber == 0) {
return;
}
- mViewItem[mCurrentItem] = buildItemFromData(0);
- if (mViewItem[mCurrentItem] == null) {
+ mViewItems[BUFFER_CENTER] = buildViewItemAt(0);
+ if (mViewItems[BUFFER_CENTER] == null) {
return;
}
- mViewItem[mCurrentItem].setLeftPosition(0);
- for (int i = mCurrentItem + 1; i < BUFFER_SIZE; i++) {
- mViewItem[i] = buildItemFromData(mViewItem[i - 1].getId() + 1);
- if (mViewItem[i] == null) {
+ mViewItems[BUFFER_CENTER].setLeftPosition(0);
+ for (int i = BUFFER_CENTER + 1; i < BUFFER_SIZE; i++) {
+ mViewItems[i] = buildViewItemAt(mViewItems[i - 1].getAdapterIndex() + 1);
+ if (mViewItems[i] == null) {
break;
}
}
- // Ensure that the views in mViewItem will layout the first in the
+ // Ensure that the views in mViewItems will layout the first in the
// center of the display upon a reload.
mCenterX = -1;
mScale = FILM_STRIP_SCALE;
adjustChildZOrder();
+
+ Log.d(TAG, "[ensureItemAtMaxSize] [ensureBufferItemsAtMaxSize] reload()");
+ ensureBufferItemsAtMaxSize();
invalidate();
if (mListener != null) {
mListener.onDataReloaded();
- mListener.onDataFocusChanged(prevId, mViewItem[mCurrentItem].getId());
+ mListener.onDataFocusChanged(prevId, mViewItems[BUFFER_CENTER].getAdapterIndex());
}
}
- private void promoteData(int itemID, int dataID) {
+ private void promoteData(int index) {
if (mListener != null) {
- mListener.onFocusedDataPromoted(dataID);
+ mListener.onFocusedDataPromoted(index);
}
}
- private void demoteData(int itemID, int dataID) {
+ private void demoteData(int index) {
if (mListener != null) {
- mListener.onFocusedDataDemoted(dataID);
+ mListener.onFocusedDataDemoted(index);
}
}
private void onEnterFilmstrip() {
if (mListener != null) {
- mListener.onEnterFilmstrip(getCurrentId());
+ mListener.onEnterFilmstrip(getCurrentItemAdapterIndex());
}
}
private void onLeaveFilmstrip() {
if (mListener != null) {
- mListener.onLeaveFilmstrip(getCurrentId());
+ mListener.onLeaveFilmstrip(getCurrentItemAdapterIndex());
}
}
private void onEnterFullScreen() {
mFullScreenUIHidden = false;
if (mListener != null) {
- mListener.onEnterFullScreenUiShown(getCurrentId());
+ mListener.onEnterFullScreenUiShown(getCurrentItemAdapterIndex());
}
}
private void onLeaveFullScreen() {
if (mListener != null) {
- mListener.onLeaveFullScreenUiShown(getCurrentId());
+ mListener.onLeaveFullScreenUiShown(getCurrentItemAdapterIndex());
}
}
private void onEnterFullScreenUiHidden() {
mFullScreenUIHidden = true;
if (mListener != null) {
- mListener.onEnterFullScreenUiHidden(getCurrentId());
+ mListener.onEnterFullScreenUiHidden(getCurrentItemAdapterIndex());
}
}
private void onLeaveFullScreenUiHidden() {
mFullScreenUIHidden = false;
if (mListener != null) {
- mListener.onLeaveFullScreenUiHidden(getCurrentId());
+ mListener.onLeaveFullScreenUiHidden(getCurrentItemAdapterIndex());
}
}
private void onEnterZoomView() {
if (mListener != null) {
- mListener.onEnterZoomView(getCurrentId());
+ mListener.onEnterZoomView(getCurrentItemAdapterIndex());
}
}
@@ -1897,23 +1941,26 @@ public class FilmstripView extends ViewGroup {
* MyController controls all the geometry animations. It passively tells the
* geometry information on demand.
*/
- private class MyController implements FilmstripController {
+ private class FilmstripControllerImpl implements FilmstripController {
private final ValueAnimator mScaleAnimator;
private ValueAnimator mZoomAnimator;
private AnimatorSet mFlingAnimator;
- private final MyScroller mScroller;
+ private final FilmstripScrollGesture mScrollGesture;
private boolean mCanStopScroll;
- private final MyScroller.Listener mScrollerListener =
- new MyScroller.Listener() {
+ private final FilmstripScrollGesture.Listener mScrollListener =
+ new FilmstripScrollGesture.Listener() {
@Override
public void onScrollUpdate(int currX, int currY) {
mCenterX = currX;
+ Log.e(TAG, "[fling] onScrollUpdate X: " + currX + ", Y: " + currY);
+
boolean stopScroll = clampCenterX();
if (stopScroll) {
+ Log.e(TAG, "[fling] stopScrolling!");
mController.stopScrolling(true);
}
invalidate();
@@ -1922,12 +1969,29 @@ public class FilmstripView extends ViewGroup {
@Override
public void onScrollEnd() {
mCanStopScroll = true;
- if (mViewItem[mCurrentItem] == null) {
+ Log.e(TAG, "[fling] onScrollEnd " + BUFFER_CENTER);
+ if (mViewItems[BUFFER_CENTER] == null) {
return;
}
- snapInCenter();
+ scrollCurrentItemToCenter();
+
+ // onScrollEnd will get called twice, once when
+ // the fling part ends, and once when the manual
+ // scroll center animation finishes. Once everything
+ // stops moving ensure that the items are loaded at
+ // full resolution.
+ if (isCurrentItemCentered()) {
+ // Since these are getting pushed into a queue,
+ // we want to ensure the item that is "most in view" is
+ // the first one rendered at max size.
+ ensureItemAtMaxSize(BUFFER_CENTER);
+ ensureItemAtMaxSize(BUFFER_CENTER + 1);
+ ensureItemAtMaxSize(BUFFER_CENTER - 1);
+ ensureItemAtMaxSize(BUFFER_CENTER + 2);
+ }
+
if (isCurrentItemCentered()
- && isViewTypeSticky(mViewItem[mCurrentItem])) {
+ && isViewTypeSticky(mViewItems[BUFFER_CENTER])) {
// Special case for the scrolling end on the camera
// preview.
goToFullScreen();
@@ -1939,7 +2003,7 @@ public class FilmstripView extends ViewGroup {
new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
- if (mViewItem[mCurrentItem] == null) {
+ if (mViewItems[BUFFER_CENTER] == null) {
return;
}
mScale = (Float) animation.getAnimatedValue();
@@ -1947,11 +2011,11 @@ public class FilmstripView extends ViewGroup {
}
};
- MyController(Context context) {
+ FilmstripControllerImpl() {
TimeInterpolator decelerateInterpolator = new DecelerateInterpolator(1.5f);
- mScroller = new MyScroller(mActivity.getAndroidContext(),
+ mScrollGesture = new FilmstripScrollGesture(mActivity.getAndroidContext(),
new Handler(mActivity.getMainLooper()),
- mScrollerListener, decelerateInterpolator);
+ mScrollListener, decelerateInterpolator);
mCanStopScroll = true;
mScaleAnimator = new ValueAnimator();
@@ -1999,12 +2063,12 @@ public class FilmstripView extends ViewGroup {
}
@Override
- public int getCurrentId() {
- return FilmstripView.this.getCurrentId();
+ public int getCurrentAdapterIndex() {
+ return FilmstripView.this.getCurrentItemAdapterIndex();
}
@Override
- public void setDataAdapter(DataAdapter adapter) {
+ public void setDataAdapter(FilmstripDataAdapter adapter) {
FilmstripView.this.setDataAdapter(adapter);
}
@@ -2029,13 +2093,13 @@ public class FilmstripView extends ViewGroup {
}
@Override
- public void setListener(FilmstripListener l) {
- FilmstripView.this.setListener(l);
+ public void setListener(FilmstripListener listener) {
+ FilmstripView.this.setListener(listener);
}
@Override
public boolean isScrolling() {
- return !mScroller.isFinished();
+ return !mScrollGesture.isFinished();
}
@Override
@@ -2043,13 +2107,13 @@ public class FilmstripView extends ViewGroup {
return mScaleAnimator.isRunning();
}
- private int estimateMinX(int dataID, int leftPos, int viewWidth) {
- return leftPos - (dataID + 100) * (viewWidth + mViewGapInPixel);
+ private int estimateMinX(int index, int leftPos, int viewWidth) {
+ return leftPos - (index + 100) * (viewWidth + mViewGapInPixel);
}
- private int estimateMaxX(int dataID, int leftPos, int viewWidth) {
+ private int estimateMaxX(int index, int leftPos, int viewWidth) {
return leftPos
- + (mDataAdapter.getTotalNumber() - dataID + 100)
+ + (mDataAdapter.getTotalNumber() - index + 100)
* (viewWidth + mViewGapInPixel);
}
@@ -2149,7 +2213,7 @@ public class FilmstripView extends ViewGroup {
if (!stopScrolling(false)) {
return;
}
- final ViewItem item = mViewItem[mCurrentItem];
+ final ViewItem item = mViewItems[BUFFER_CENTER];
if (item == null) {
return;
}
@@ -2164,11 +2228,11 @@ public class FilmstripView extends ViewGroup {
// Estimation of possible length on the left. To ensure the
// velocity doesn't become too slow eventually, we add a huge number
// to the estimated maximum.
- int minX = estimateMinX(item.getId(), item.getLeftPosition(), w);
+ int minX = estimateMinX(item.getAdapterIndex(), item.getLeftPosition(), w);
// Estimation of possible length on the right. Likewise, exaggerate
// the possible maximum too.
- int maxX = estimateMaxX(item.getId(), item.getLeftPosition(), w);
- mScroller.fling(mCenterX, 0, (int) -velocityX, 0, minX, maxX, 0, 0);
+ int maxX = estimateMaxX(item.getAdapterIndex(), item.getLeftPosition(), w);
+ mScrollGesture.fling(mCenterX, 0, (int) -velocityX, 0, minX, maxX, 0, 0);
}
void flingInsideZoomView(float velocityX, float velocityY) {
@@ -2176,7 +2240,7 @@ public class FilmstripView extends ViewGroup {
return;
}
- final ViewItem current = mViewItem[mCurrentItem];
+ final ViewItem current = mViewItems[BUFFER_CENTER];
if (current == null) {
return;
}
@@ -2266,7 +2330,7 @@ public class FilmstripView extends ViewGroup {
} else if (!mCanStopScroll && !forced) {
return false;
}
- mScroller.forceFinished(true);
+ mScrollGesture.forceFinished(true);
return true;
}
@@ -2276,32 +2340,32 @@ public class FilmstripView extends ViewGroup {
@Override
public void scrollToPosition(int position, int duration, boolean interruptible) {
- if (mViewItem[mCurrentItem] == null) {
+ if (mViewItems[BUFFER_CENTER] == null) {
return;
}
mCanStopScroll = interruptible;
- mScroller.startScroll(mCenterX, 0, position - mCenterX, 0, duration);
+ mScrollGesture.startScroll(mCenterX, position - mCenterX, duration);
}
@Override
public boolean goToNextItem() {
- return goToItem(mCurrentItem + 1);
+ return goToItem(BUFFER_CENTER + 1);
}
@Override
public boolean goToPreviousItem() {
- return goToItem(mCurrentItem - 1);
+ return goToItem(BUFFER_CENTER - 1);
}
private boolean goToItem(int itemIndex) {
- final ViewItem nextItem = mViewItem[itemIndex];
+ final ViewItem nextItem = mViewItems[itemIndex];
if (nextItem == null) {
return false;
}
stopScrolling(true);
scrollToPosition(nextItem.getCenterX(), GEOMETRY_ADJUST_TIME_MS * 2, false);
- if (isViewTypeSticky(mViewItem[mCurrentItem])) {
+ if (isViewTypeSticky(mViewItems[BUFFER_CENTER])) {
// Special case when moving from camera preview.
scaleTo(FILM_STRIP_SCALE, GEOMETRY_ADJUST_TIME_MS);
}
@@ -2309,7 +2373,7 @@ public class FilmstripView extends ViewGroup {
}
private void scaleTo(float scale, int duration) {
- if (mViewItem[mCurrentItem] == null) {
+ if (mViewItems[BUFFER_CENTER] == null) {
return;
}
stopScale();
@@ -2320,7 +2384,7 @@ public class FilmstripView extends ViewGroup {
@Override
public void goToFilmstrip() {
- if (mViewItem[mCurrentItem] == null) {
+ if (mViewItems[BUFFER_CENTER] == null) {
return;
}
if (mScale == FILM_STRIP_SCALE) {
@@ -2328,9 +2392,9 @@ public class FilmstripView extends ViewGroup {
}
scaleTo(FILM_STRIP_SCALE, GEOMETRY_ADJUST_TIME_MS);
- final ViewItem currItem = mViewItem[mCurrentItem];
- final ViewItem nextItem = mViewItem[mCurrentItem + 1];
- if (currItem.getId() == 0 && isViewTypeSticky(currItem) && nextItem != null) {
+ final ViewItem currItem = mViewItems[BUFFER_CENTER];
+ final ViewItem nextItem = mViewItems[BUFFER_CENTER + 1];
+ if (currItem.getAdapterIndex() == 0 && isViewTypeSticky(currItem) && nextItem != null) {
// Deal with the special case of swiping in camera preview.
scrollToPosition(nextItem.getCenterX(), GEOMETRY_ADJUST_TIME_MS, false);
}
@@ -2366,20 +2430,19 @@ public class FilmstripView extends ViewGroup {
// Hide everything on the left
// TODO: Need to find a better way to toggle the visibility of views
// around the current view.
- for (int i = 0; i < mCurrentItem; i++) {
- if (i == mCurrentItem || mViewItem[i] == null) {
- continue;
+ for (int i = 0; i < BUFFER_CENTER; i++) {
+ if (mViewItems[i] != null) {
+ mViewItems[i].setVisibility(visible ? VISIBLE : INVISIBLE);
}
- mViewItem[i].setVisibility(visible ? VISIBLE : INVISIBLE);
}
}
private Uri getCurrentUri() {
- ViewItem curr = mViewItem[mCurrentItem];
+ ViewItem curr = mViewItems[BUFFER_CENTER];
if (curr == null) {
return Uri.EMPTY;
}
- return mDataAdapter.getImageData(curr.getId()).getUri();
+ return mDataAdapter.getFilmstripItemAt(curr.getAdapterIndex()).getData().getUri();
}
/**
@@ -2388,18 +2451,18 @@ public class FilmstripView extends ViewGroup {
* make the view same size as the image, in pixels.
*/
private float getCurrentDataMaxScale(boolean allowOverScale) {
- ViewItem curr = mViewItem[mCurrentItem];
+ ViewItem curr = mViewItems[BUFFER_CENTER];
if (curr == null) {
return FULL_SCREEN_SCALE;
}
- ImageData imageData = mDataAdapter.getImageData(curr.getId());
- if (imageData == null || !imageData.isUIActionSupported(ImageData.ACTION_ZOOM)) {
+ FilmstripItem imageData = mDataAdapter.getFilmstripItemAt(curr.getAdapterIndex());
+ if (imageData == null || !imageData.getAttributes().canZoomInPlace()) {
return FULL_SCREEN_SCALE;
}
- float imageWidth = imageData.getWidth();
- if (imageData.getRotation() == 90
- || imageData.getRotation() == 270) {
- imageWidth = imageData.getHeight();
+ float imageWidth = imageData.getData().getDimensions().getWidth();
+ if (imageData.getData().getOrientation() == 90
+ || imageData.getData().getOrientation() == 270) {
+ imageWidth = imageData.getData().getDimensions().getHeight();
}
float scale = imageWidth / curr.getWidth();
if (allowOverScale) {
@@ -2415,12 +2478,12 @@ public class FilmstripView extends ViewGroup {
if (!inZoomView()) {
return;
}
- ViewItem curr = mViewItem[mCurrentItem];
+ ViewItem curr = mViewItems[BUFFER_CENTER];
if (curr == null) {
return;
}
- ImageData imageData = mDataAdapter.getImageData(curr.getId());
- if (!imageData.isUIActionSupported(ImageData.ACTION_ZOOM)) {
+ FilmstripItem imageData = mDataAdapter.getFilmstripItemAt(curr.getAdapterIndex());
+ if (!imageData.getAttributes().canZoomInPlace()) {
return;
}
Uri uri = getCurrentUri();
@@ -2428,7 +2491,7 @@ public class FilmstripView extends ViewGroup {
if (uri == null || uri == Uri.EMPTY) {
return;
}
- int orientation = imageData.getRotation();
+ int orientation = imageData.getData().getOrientation();
mZoomView.loadBitmap(uri, orientation, viewRect);
}
@@ -2438,11 +2501,11 @@ public class FilmstripView extends ViewGroup {
@Override
public void goToFirstItem() {
- if (mViewItem[mCurrentItem] == null) {
+ if (mViewItems[BUFFER_CENTER] == null) {
return;
}
resetZoomView();
- // TODO: animate to camera if it is still in the mViewItem buffer
+ // TODO: animate to camera if it is still in the mViewItems buffer
// versus a full reload which will perform an immediate transition
reload();
}
@@ -2461,10 +2524,10 @@ public class FilmstripView extends ViewGroup {
}
private boolean isCurrentItemCentered() {
- return mViewItem[mCurrentItem].getCenterX() == mCenterX;
+ return mViewItems[BUFFER_CENTER].getCenterX() == mCenterX;
}
- private static class MyScroller {
+ private static class FilmstripScrollGesture {
public interface Listener {
public void onScrollUpdate(int currX, int currY);
@@ -2482,6 +2545,7 @@ public class FilmstripView extends ViewGroup {
public void run() {
boolean newPosition = mScroller.computeScrollOffset();
if (!newPosition) {
+ Log.e(TAG, "[fling] onScrollEnd from computeScrollOffset");
mListener.onScrollEnd();
return;
}
@@ -2503,27 +2567,32 @@ public class FilmstripView extends ViewGroup {
new Animator.AnimatorListener() {
@Override
public void onAnimationCancel(Animator animation) {
+ Log.e(TAG, "[fling] mXScrollAnimatorListener.onAnimationCancel");
// Do nothing.
}
@Override
public void onAnimationEnd(Animator animation) {
+
+ Log.e(TAG, "[fling] onScrollEnd from mXScrollAnimatorListener.onAnimationEnd");
mListener.onScrollEnd();
}
@Override
public void onAnimationRepeat(Animator animation) {
+ Log.e(TAG, "[fling] mXScrollAnimatorListener.onAnimationRepeat");
// Do nothing.
}
@Override
public void onAnimationStart(Animator animation) {
+ Log.e(TAG, "[fling] mXScrollAnimatorListener.onAnimationStart");
// Do nothing.
}
};
- public MyScroller(Context ctx, Handler handler, Listener listener,
- TimeInterpolator interpolator) {
+ public FilmstripScrollGesture(Context ctx, Handler handler, Listener listener,
+ TimeInterpolator interpolator) {
mHandler = handler;
mListener = listener;
mScroller = new Scroller(ctx);
@@ -2548,7 +2617,7 @@ public class FilmstripView extends ViewGroup {
}
/** Only starts and updates scroll in x-axis. */
- public void startScroll(int startX, int startY, int dx, int dy, int duration) {
+ public void startScroll(int startX, int dx, int duration) {
mXScrollAnimator.cancel();
mXScrollAnimator.setDuration(duration);
mXScrollAnimator.setIntValues(startX, startX + dx);
@@ -2575,7 +2644,7 @@ public class FilmstripView extends ViewGroup {
}
}
- private class MyGestureReceiver implements FilmstripGestureRecognizer.Listener {
+ private class FilmstripGestures implements FilmstripGestureRecognizer.Listener {
private static final int SCROLL_DIR_NONE = 0;
private static final int SCROLL_DIR_VERTICAL = 1;
@@ -2589,7 +2658,7 @@ public class FilmstripView extends ViewGroup {
@Override
public boolean onSingleTapUp(float x, float y) {
- ViewItem centerItem = mViewItem[mCurrentItem];
+ ViewItem centerItem = mViewItems[BUFFER_CENTER];
if (inFilmstrip()) {
if (centerItem != null && centerItem.areaContains(x, y)) {
mController.goToFullScreen();
@@ -2610,7 +2679,7 @@ public class FilmstripView extends ViewGroup {
@Override
public boolean onDoubleTap(float x, float y) {
- ViewItem current = mViewItem[mCurrentItem];
+ ViewItem current = mViewItems[BUFFER_CENTER];
if (current == null) {
return false;
}
@@ -2625,7 +2694,7 @@ public class FilmstripView extends ViewGroup {
}
if (inFullScreen()) {
mController.zoomAt(current, x, y);
- checkItemAtMaxSize();
+ ensureItemAtMaxSize(BUFFER_CENTER);
return true;
} else if (mScale > FULL_SCREEN_SCALE) {
// In zoom view.
@@ -2648,7 +2717,7 @@ public class FilmstripView extends ViewGroup {
@Override
public boolean onUp(float x, float y) {
- ViewItem currItem = mViewItem[mCurrentItem];
+ ViewItem currItem = mViewItems[BUFFER_CENTER];
if (currItem == null) {
return false;
}
@@ -2667,88 +2736,86 @@ public class FilmstripView extends ViewGroup {
float speedY = Math.abs(y - mLastDownY)
/ (SystemClock.uptimeMillis() - mLastDownTime);
for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewItem[i] == null) {
+ if (mViewItems[i] == null) {
continue;
}
- float transY = mViewItem[i].getTranslationY();
+ float transY = mViewItems[i].getTranslationY();
if (transY == 0) {
continue;
}
- int id = mViewItem[i].getId();
+ int index = mViewItems[i].getAdapterIndex();
- if (mDataAdapter.getImageData(id)
- .isUIActionSupported(ImageData.ACTION_DEMOTE)
+ if (mDataAdapter.getFilmstripItemAt(index).getAttributes().canSwipeAway()
&& ((transY > promoteHeight)
|| (transY > velocityPromoteHeight && speedY > PROMOTE_VELOCITY))) {
- demoteData(i, id);
- } else if (mDataAdapter.getImageData(id)
- .isUIActionSupported(ImageData.ACTION_PROMOTE)
+ demoteData(index);
+ } else if (mDataAdapter.getFilmstripItemAt(index).getAttributes().canSwipeAway()
&& (transY < -promoteHeight
|| (transY < -velocityPromoteHeight && speedY > PROMOTE_VELOCITY))) {
- promoteData(i, id);
+ promoteData(index);
} else {
// put the view back.
- slideViewBack(mViewItem[i]);
+ slideViewBack(mViewItems[i]);
}
}
// The data might be changed. Re-check.
- currItem = mViewItem[mCurrentItem];
+ currItem = mViewItems[BUFFER_CENTER];
if (currItem == null) {
return true;
}
- int currId = currItem.getId();
+ int currId = currItem.getAdapterIndex();
if (mCenterX > currItem.getCenterX() + CAMERA_PREVIEW_SWIPE_THRESHOLD && currId == 0 &&
- isViewTypeSticky(currItem) && mDataIdOnUserScrolling == 0) {
+ isViewTypeSticky(currItem) && mAdapterIndexUserIsScrollingOver == 0) {
mController.goToFilmstrip();
// Special case to go from camera preview to the next photo.
- if (mViewItem[mCurrentItem + 1] != null) {
+ if (mViewItems[BUFFER_CENTER + 1] != null) {
mController.scrollToPosition(
- mViewItem[mCurrentItem + 1].getCenterX(),
+ mViewItems[BUFFER_CENTER + 1].getCenterX(),
GEOMETRY_ADJUST_TIME_MS, false);
} else {
// No next photo.
- snapInCenter();
+ scrollCurrentItemToCenter();
}
}
if (isCurrentItemCentered() && currId == 0 && isViewTypeSticky(currItem)) {
mController.goToFullScreen();
} else {
- if (mDataIdOnUserScrolling == 0 && currId != 0) {
+ if (mAdapterIndexUserIsScrollingOver == 0 && currId != 0) {
// Special case to go to filmstrip when the user scroll away
// from the camera preview and the current one is not the
// preview anymore.
mController.goToFilmstrip();
- mDataIdOnUserScrolling = currId;
+ mAdapterIndexUserIsScrollingOver = currId;
}
- snapInCenter();
+ scrollCurrentItemToCenter();
}
return false;
}
@Override
public void onLongPress(float x, float y) {
- final int dataId = getCurrentId();
- if (dataId == -1) {
+ final int index = getCurrentItemAdapterIndex();
+ if (index == -1) {
return;
}
- mListener.onFocusedDataLongPressed(dataId);
+ mListener.onFocusedDataLongPressed(index);
}
@Override
public boolean onScroll(float x, float y, float dx, float dy) {
- final ViewItem currItem = mViewItem[mCurrentItem];
+ final ViewItem currItem = mViewItems[BUFFER_CENTER];
if (currItem == null) {
return false;
}
- if (inFullScreen() && !mDataAdapter.canSwipeInFullScreen(currItem.getId())) {
+ if (inFullScreen() && !mDataAdapter.canSwipeInFullScreen(currItem.getAdapterIndex())) {
return false;
}
hideZoomView();
// When image is zoomed in to be bigger than the screen
if (inZoomView()) {
- ViewItem curr = mViewItem[mCurrentItem];
+ ViewItem curr = mViewItems[BUFFER_CENTER];
float transX = curr.getTranslationX() * mScale - dx;
float transY = curr.getTranslationY() * mScale - dy;
curr.updateTransform(transX, transY, mScale, mScale, mDrawArea.width(),
@@ -2760,7 +2827,8 @@ public class FilmstripView extends ViewGroup {
mController.stopScrolling(true);
if (!mIsUserScrolling) {
mIsUserScrolling = true;
- mDataIdOnUserScrolling = mViewItem[mCurrentItem].getId();
+ mAdapterIndexUserIsScrollingOver =
+ mViewItems[BUFFER_CENTER].getAdapterIndex();
}
if (inFilmstrip()) {
// Disambiguate horizontal/vertical first.
@@ -2769,7 +2837,8 @@ public class FilmstripView extends ViewGroup {
SCROLL_DIR_VERTICAL;
}
if (mScrollingDirection == SCROLL_DIR_HORIZONTAL) {
- if (mCenterX == currItem.getCenterX() && currItem.getId() == 0 && dx < 0) {
+ if (mCenterX == currItem.getCenterX() && currItem.getAdapterIndex() == 0 &&
+ dx < 0) {
// Already at the beginning, don't process the swipe.
mIsUserScrolling = false;
mScrollingDirection = SCROLL_DIR_NONE;
@@ -2781,10 +2850,10 @@ public class FilmstripView extends ViewGroup {
int hit = 0;
Rect hitRect = new Rect();
for (; hit < BUFFER_SIZE; hit++) {
- if (mViewItem[hit] == null) {
+ if (mViewItems[hit] == null) {
continue;
}
- mViewItem[hit].getHitRect(hitRect);
+ mViewItems[hit].getHitRect(hitRect);
if (hitRect.contains((int) x, (int) y)) {
break;
}
@@ -2794,21 +2863,22 @@ public class FilmstripView extends ViewGroup {
return true;
}
- ImageData data = mDataAdapter.getImageData(mViewItem[hit].getId());
- float transY = mViewItem[hit].getTranslationY() - dy / mScale;
- if (!data.isUIActionSupported(ImageData.ACTION_DEMOTE) &&
+ FilmstripItem data = mDataAdapter.getFilmstripItemAt(
+ mViewItems[hit].getAdapterIndex());
+ float transY = mViewItems[hit].getTranslationY() - dy / mScale;
+ if (!data.getAttributes().canSwipeAway() &&
transY > 0f) {
transY = 0f;
}
- if (!data.isUIActionSupported(ImageData.ACTION_PROMOTE) &&
+ if (!data.getAttributes().canSwipeAway() &&
transY < 0f) {
transY = 0f;
}
- mViewItem[hit].setTranslationY(transY);
+ mViewItems[hit].setTranslationY(transY);
}
} else if (inFullScreen()) {
- if (mViewItem[mCurrentItem] == null || (deltaX < 0 && mCenterX <=
- currItem.getCenterX() && currItem.getId() == 0)) {
+ if (mViewItems[BUFFER_CENTER] == null || (deltaX < 0 && mCenterX <=
+ currItem.getCenterX() && currItem.getAdapterIndex() == 0)) {
return false;
}
// Multiplied by 1.2 to make it more easy to swipe.
@@ -2845,11 +2915,11 @@ public class FilmstripView extends ViewGroup {
@Override
public boolean onFling(float velocityX, float velocityY) {
- final ViewItem currItem = mViewItem[mCurrentItem];
+ final ViewItem currItem = mViewItems[BUFFER_CENTER];
if (currItem == null) {
return false;
}
- if (!mDataAdapter.canSwipeInFullScreen(currItem.getId())) {
+ if (!mDataAdapter.canSwipeInFullScreen(currItem.getAdapterIndex())) {
return false;
}
if (inZoomView()) {
@@ -2875,7 +2945,7 @@ public class FilmstripView extends ViewGroup {
currItemCenterX, GEOMETRY_ADJUST_TIME_MS, true);
return true;
}
- ViewItem prevItem = mViewItem[mCurrentItem - 1];
+ ViewItem prevItem = mViewItems[BUFFER_CENTER - 1];
if (prevItem == null) {
return false;
}
@@ -2890,7 +2960,7 @@ public class FilmstripView extends ViewGroup {
currItemCenterX, GEOMETRY_ADJUST_TIME_MS, true);
return true;
}
- final ViewItem nextItem = mViewItem[mCurrentItem + 1];
+ final ViewItem nextItem = mViewItems[BUFFER_CENTER + 1];
if (nextItem == null) {
return false;
}
@@ -2978,7 +3048,7 @@ public class FilmstripView extends ViewGroup {
if (!inZoomView()) {
mController.setSurroundingViewsVisible(false);
}
- ViewItem curr = mViewItem[mCurrentItem];
+ ViewItem curr = mViewItems[BUFFER_CENTER];
// Make sure the image is not overly scaled
newScale = Math.min(newScale, mMaxScale);
if (newScale == mScale) {
@@ -2992,7 +3062,7 @@ public class FilmstripView extends ViewGroup {
} else {
onEnterZoomView();
}
- checkItemAtMaxSize();
+ ensureItemAtMaxSize(BUFFER_CENTER);
}
return true;
}