summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Kolb <kolby@google.com>2011-08-09 10:24:41 -0700
committerMichael Kolb <kolby@google.com>2011-08-15 13:31:03 -0700
commitc3af06776be83ba64a0d3549cb72ca6e5e7f03cd (patch)
tree60d1a15205ac0b46f94528c0da0963a79f6d547e /src
parent8d5af2d0208aa5b5197f50e12ba11c5565d74dc4 (diff)
downloadpackages_apps_Browser-c3af06776be83ba64a0d3549cb72ca6e5e7f03cd.zip
packages_apps_Browser-c3af06776be83ba64a0d3549cb72ca6e5e7f03cd.tar.gz
packages_apps_Browser-c3af06776be83ba64a0d3549cb72ca6e5e7f03cd.tar.bz2
Tab switcher animation
Bug: 5123884 first step towards animations between browser and tab switcher Change-Id: I1d959d42d0036f3c4498972fcc8ad434fa7f4437
Diffstat (limited to 'src')
-rw-r--r--src/com/android/browser/BrowserActivity.java31
-rw-r--r--src/com/android/browser/Controller.java28
-rw-r--r--src/com/android/browser/NavScreen.java30
-rw-r--r--src/com/android/browser/NavTabView.java10
-rw-r--r--src/com/android/browser/PhoneUi.java201
-rw-r--r--src/com/android/browser/Tab.java2
-rw-r--r--src/com/android/browser/UiController.java2
-rw-r--r--src/com/android/browser/view/Gallery.java62
8 files changed, 334 insertions, 32 deletions
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 6ec6071..084ace0 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -28,6 +28,7 @@ import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
@@ -271,4 +272,34 @@ public class BrowserActivity extends Activity {
return mController.onSearchRequested();
}
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ return mController.dispatchKeyEvent(event)
+ || super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+ return mController.dispatchKeyShortcutEvent(event)
+ || super.dispatchKeyShortcutEvent(event);
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ return mController.dispatchTouchEvent(ev)
+ || super.dispatchTouchEvent(ev);
+ }
+
+ @Override
+ public boolean dispatchTrackballEvent(MotionEvent ev) {
+ return mController.dispatchTrackballEvent(ev)
+ || super.dispatchTrackballEvent(ev);
+ }
+
+ @Override
+ public boolean dispatchGenericMotionEvent(MotionEvent ev) {
+ return mController.dispatchGenericMotionEvent(ev) ||
+ super.dispatchGenericMotionEvent(ev);
+ }
+
}
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 2144dd0..3f126c0 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -64,6 +64,7 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
+import android.view.MotionEvent;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
@@ -212,6 +213,8 @@ public class Controller
private boolean mSimulateActionBarOverlayMode;
+ private boolean mBlockEvents;
+
private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
@Override
public Void doInBackground(File... files) {
@@ -2675,4 +2678,29 @@ public class Controller
return mUi.shouldCaptureThumbnails();
}
+ @Override
+ public void setBlockEvents(boolean block) {
+ mBlockEvents = block;
+ }
+
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ return mBlockEvents;
+ }
+
+ public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+ return mBlockEvents;
+ }
+
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ return mBlockEvents;
+ }
+
+ public boolean dispatchTrackballEvent(MotionEvent ev) {
+ return mBlockEvents;
+ }
+
+ public boolean dispatchGenericMotionEvent(MotionEvent ev) {
+ return mBlockEvents;
+ }
+
}
diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java
index 22f6257..768f9ba 100644
--- a/src/com/android/browser/NavScreen.java
+++ b/src/com/android/browser/NavScreen.java
@@ -39,12 +39,17 @@ import android.widget.TextView;
import com.android.browser.NavTabGallery.OnRemoveListener;
import com.android.browser.TabControl.OnThumbnailUpdatedListener;
+import com.android.browser.view.Gallery.OnScrollFinishedListener;
import java.util.HashMap;
public class NavScreen extends RelativeLayout
implements OnClickListener, OnMenuItemClickListener, OnThumbnailUpdatedListener {
+
+ private static final int SCROLL_MIN = 200;
+ private static final int SCROLL_FACTOR = 20;
+
UiController mUiController;
PhoneUi mUi;
Tab mTab;
@@ -126,11 +131,11 @@ public class NavScreen extends RelativeLayout
TabControl tc = mUiController.getTabControl();
mTabViews = new HashMap<Tab, View>(tc.getTabCount());
mAdapter = new TabAdapter(mContext, tc);
- mScroller.setAdapter(mAdapter);
mScroller.setOrientation(mOrientation == Configuration.ORIENTATION_LANDSCAPE
? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
// update state for active tab
- mScroller.setSelection(mUiController.getTabControl().getTabPosition(mUi.getActiveTab()));
+ mScroller.setAdapter(mAdapter,
+ mUiController.getTabControl().getTabPosition(mUi.getActiveTab()));
mScroller.setOnRemoveListener(new OnRemoveListener() {
public void onRemovePosition(int pos) {
Tab tab = mAdapter.getItem(pos);
@@ -185,21 +190,28 @@ public class NavScreen extends RelativeLayout
// need to call openTab explicitely with setactive false
Tab tab = mUiController.openTab(BrowserSettings.getInstance().getHomePage(),
false, false, false);
- mAdapter.notifyDataSetChanged();
+ int duration = 0;
if (tab != null) {
- // set tab as the selected in flipper, then hide
+ mUiController.setBlockEvents(true);
+ int oldsel = mScroller.getSelectedItemPosition();
final int tix = mUi.mTabControl.getTabPosition(tab);
- mScroller.setSelection(tix);
- postDelayed(new Runnable() {
+ duration = SCROLL_MIN + SCROLL_FACTOR * Math.abs(oldsel - tix);
+ mScroller.handleDataChanged();
+ mScroller.smoothScrollToPosition(tix, duration, new OnScrollFinishedListener() {
@Override
- public void run() {
+ public void onScrollFinished() {
+ mUiController.setBlockEvents(false);
mUi.hideNavScreen(true);
switchToSelected();
}
- }, 100);
+ });
}
}
+ View getSelectedTabView() {
+ return mScroller.getSelectedTab();
+ }
+
private void switchToSelected() {
Tab tab = (Tab) mScroller.getSelectedItem();
if (tab != mUi.getActiveTab()) {
@@ -243,7 +255,7 @@ public class NavScreen extends RelativeLayout
public View getView(final int position, View convertView, ViewGroup parent) {
final NavTabView tabview = new NavTabView(mActivity);
final Tab tab = getItem(position);
- tabview.setWebView(mUi, tab);
+ tabview.setWebView(tab);
mTabViews.put(tab, tabview.mImage);
tabview.setOnClickListener(new OnClickListener() {
@Override
diff --git a/src/com/android/browser/NavTabView.java b/src/com/android/browser/NavTabView.java
index ed6b63d..07ac164 100644
--- a/src/com/android/browser/NavTabView.java
+++ b/src/com/android/browser/NavTabView.java
@@ -21,12 +21,15 @@ import android.graphics.Bitmap;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class NavTabView extends LinearLayout {
+ private ViewGroup mContent;
private Tab mTab;
private ImageView mClose;
private TextView mTitle;
@@ -52,6 +55,7 @@ public class NavTabView extends LinearLayout {
private void init() {
LayoutInflater.from(mContext).inflate(R.layout.nav_tab_view, this);
+ mContent = (ViewGroup) findViewById(R.id.main);
mClose = (ImageView) findViewById(R.id.closetab);
mTitle = (TextView) findViewById(R.id.title);
mTitleBar = findViewById(R.id.titlebar);
@@ -92,7 +96,11 @@ public class NavTabView extends LinearLayout {
return mHighlighted;
}
- protected void setWebView(PhoneUi ui, Tab tab) {
+ protected void setWebView(WebView w) {
+ mContent.addView(w, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ }
+
+ protected void setWebView(Tab tab) {
mTab = tab;
setTitle();
Bitmap image = tab.getScreenshot();
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index 863a628..d77fcdb 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -16,17 +16,29 @@
package com.android.browser;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.util.Log;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
+import android.view.animation.DecelerateInterpolator;
import android.webkit.WebView;
import android.widget.FrameLayout;
+import android.widget.ImageView;
import com.android.browser.UrlInputView.StateListener;
@@ -241,15 +253,72 @@ public class PhoneUi extends BaseUi {
updateUrlBarAutoShowManagerTarget();
}
+ @Override
+ public boolean isWebShowing() {
+ return super.isWebShowing() && mNavScreen == null;
+ }
+
+ @Override
+ public void showWeb(boolean animate) {
+ super.showWeb(animate);
+ hideNavScreen(animate);
+ }
+
void showNavScreen() {
- mActiveTab.capture();
- detachTab(mActiveTab);
+ mUiController.setBlockEvents(true);
mNavScreen = new NavScreen(mActivity, mUiController, this);
- // Add the custom view to its container.
+ mActiveTab.capture();
+ // Add the custom view to its container
mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
- mContentView.setVisibility(View.GONE);
+ AnimScreen ascreen = new AnimScreen(mActivity, getTitleBar(), getWebView());
+ final View animView = ascreen.mMain;
+ mCustomViewContainer.addView(animView, COVER_SCREEN_PARAMS);
mCustomViewContainer.setVisibility(View.VISIBLE);
mCustomViewContainer.bringToFront();
+ View target = ((NavTabView) mNavScreen.mScroller.getSelectedView()).mImage;
+ int fromLeft = 0;
+ int fromTop = getTitleBar().getHeight();
+ int fromRight = mContentView.getWidth();
+ int fromBottom = mContentView.getHeight();
+ int width = target.getWidth();
+ int height = target.getHeight();
+ int toLeft = (mContentView.getWidth() - width) / 2;
+ int toTop = fromTop + (mContentView.getHeight() - fromTop - height) / 2;
+ int toRight = toLeft + width;
+ int toBottom = toTop + height;
+ float scaleFactor = width / (float) mContentView.getWidth();
+ detachTab(mActiveTab);
+ mContentView.setVisibility(View.GONE);
+ AnimatorSet inanim = new AnimatorSet();
+ ObjectAnimator tx = ObjectAnimator.ofInt(ascreen.mContent, "left",
+ fromLeft, toLeft);
+ ObjectAnimator ty = ObjectAnimator.ofInt(ascreen.mContent, "top",
+ fromTop, toTop);
+ ObjectAnimator tr = ObjectAnimator.ofInt(ascreen.mContent, "right",
+ fromRight, toRight);
+ ObjectAnimator tb = ObjectAnimator.ofInt(ascreen.mContent, "bottom",
+ fromBottom, toBottom);
+ ObjectAnimator title = ObjectAnimator.ofFloat(ascreen.mTitle, "alpha",
+ 1f, 0f);
+ ObjectAnimator content = ObjectAnimator.ofFloat(ascreen.mContent, "alpha",
+ 1f, 0f);
+ ObjectAnimator sx = ObjectAnimator.ofFloat(ascreen, "scaleFactor",
+ 1f, scaleFactor);
+ inanim.playTogether(tx, ty, tr, tb, title, content, sx);
+ inanim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator anim) {
+ mCustomViewContainer.removeView(animView);
+ finishAnimationIn();
+ mUiController.setBlockEvents(false);
+ }
+ });
+ inanim.setInterpolator(new DecelerateInterpolator(2f));
+ inanim.setDuration(300);
+ inanim.start();
+ }
+
+ private void finishAnimationIn() {
// notify accessibility manager about the screen change
mNavScreen.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
mTabControl.setOnThumbnailUpdatedListener(mNavScreen);
@@ -257,14 +326,67 @@ public class PhoneUi extends BaseUi {
void hideNavScreen(boolean animate) {
if (mNavScreen == null) return;
+ final Tab tab = mNavScreen.getSelectedTab();
+ if ((tab != null) && !animate) {
+ finishAnimateOut(tab);
+ }
+ NavTabView tabview = (NavTabView) mNavScreen.getSelectedTabView();
+ if (tabview == null) {
+ finishAnimateOut(tab);
+ }
+ mUiController.setBlockEvents(true);
+ mUiController.setActiveTab(tab);
+ mContentView.setVisibility(View.VISIBLE);
+ final AnimScreen screen = new AnimScreen(mActivity, tab.getScreenshot());
+ View target = ((NavTabView) mNavScreen.mScroller.getSelectedView()).mImage;
+ int toLeft = 0;
+ int toTop = getTitleBar().getHeight();
+ int toRight = mContentView.getWidth();
+ int width = target.getWidth();
+ int height = target.getHeight();
+ int[] pos = new int[2];
+ tabview.mImage.getLocationInWindow(pos);
+ int fromLeft = pos[0];
+ int fromTop = pos[1];
+ int fromRight = fromLeft + width;
+ int fromBottom = fromTop + height;
+ float scaleFactor = mContentView.getWidth() / (float) width;
+ int toBottom = (int) (height * scaleFactor);
+ screen.mMain.setAlpha(0f);
+ mCustomViewContainer.addView(screen.mMain, COVER_SCREEN_PARAMS);
+ AnimatorSet animSet = new AnimatorSet();
+ ObjectAnimator l = ObjectAnimator.ofInt(screen.mContent, "left",
+ fromLeft, toLeft);
+ ObjectAnimator t = ObjectAnimator.ofInt(screen.mContent, "top",
+ fromTop, toTop);
+ ObjectAnimator r = ObjectAnimator.ofInt(screen.mContent, "right",
+ fromRight, toRight);
+ ObjectAnimator b = ObjectAnimator.ofInt(screen.mContent, "bottom",
+ fromBottom, toBottom);
+ ObjectAnimator scale = ObjectAnimator.ofFloat(screen, "scaleFactor",
+ 1f, scaleFactor);
+ ObjectAnimator alpha = ObjectAnimator.ofFloat(screen.mMain, "alpha", 1f, 1f);
+ ObjectAnimator otheralpha = ObjectAnimator.ofFloat(mCustomViewContainer, "alpha", 1f, 0f);
+ alpha.setStartDelay(100);
+ animSet.playTogether(l, t, r, b, scale, alpha, otheralpha);
+ animSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator anim) {
+ mCustomViewContainer.removeView(screen.mMain);
+ finishAnimateOut(tab);
+ mUiController.setBlockEvents(false);
+ }
+ });
+ animSet.setDuration(250);
+ animSet.start();
+ }
+
+ private void finishAnimateOut(Tab tab) {
mTabControl.setOnThumbnailUpdatedListener(null);
- Tab tab = mNavScreen.getSelectedTab();
mCustomViewContainer.removeView(mNavScreen);
+ mCustomViewContainer.setAlpha(1f);
mNavScreen = null;
mCustomViewContainer.setVisibility(View.GONE);
- mUiController.setActiveTab(tab);
- // Show the content view.
- mContentView.setVisibility(View.VISIBLE);
}
@Override
@@ -285,15 +407,62 @@ public class PhoneUi extends BaseUi {
return true;
}
- @Override
- public boolean isWebShowing() {
- return super.isWebShowing() && mNavScreen == null;
- }
+ static class AnimScreen {
+
+ private View mMain;
+ private ImageView mTitle;
+ private ImageView mContent;
+ private float mScale;
+
+ public AnimScreen(Context ctx, TitleBar tbar, WebView web) {
+ mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen,
+ null);
+ mContent = (ImageView) mMain.findViewById(R.id.content);
+ mContent.setTop(tbar.getHeight());
+
+ mTitle = (ImageView) mMain.findViewById(R.id.title);
+ Bitmap bm1 = Bitmap.createBitmap(tbar.getWidth(), tbar.getHeight(),
+ Bitmap.Config.RGB_565);
+ Canvas c1 = new Canvas(bm1);
+ tbar.draw(c1);
+ mTitle.setImageBitmap(bm1);
+ int h = web.getHeight() - tbar.getHeight();
+ Bitmap bm2 = Bitmap.createBitmap(web.getWidth(), h,
+ Bitmap.Config.RGB_565);
+ Canvas c2 = new Canvas(bm2);
+ int tx = web.getScrollX();
+ int ty = web.getScrollY();
+ c2.translate(-tx, -ty - tbar.getHeight());
+ web.draw(c2);
+ mContent.setImageBitmap(bm2);
+ mContent.setScaleType(ImageView.ScaleType.MATRIX);
+ mContent.setImageMatrix(new Matrix());
+ mScale = 1.0f;
+ setScaleFactor(getScaleFactor());
+ }
+
+ public AnimScreen(Context ctx, Bitmap image) {
+ mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen,
+ null);
+ mContent = (ImageView) mMain.findViewById(R.id.content);
+ mContent.setImageBitmap(image);
+ mContent.setScaleType(ImageView.ScaleType.MATRIX);
+ mContent.setImageMatrix(new Matrix());
+ mScale = 1.0f;
+ setScaleFactor(getScaleFactor());
+ }
+
+ public void setScaleFactor(float sf) {
+ mScale = sf;
+ Matrix m = new Matrix();
+ m.postScale(sf,sf);
+ mContent.setImageMatrix(m);
+ }
+
+ public float getScaleFactor() {
+ return mScale;
+ }
- @Override
- public void showWeb(boolean animate) {
- super.showWeb(animate);
- hideNavScreen(animate);
}
}
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 78ae987..c6808e0 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -31,6 +31,7 @@ import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Picture;
import android.net.Uri;
import android.net.http.SslError;
@@ -1455,6 +1456,7 @@ class Tab implements PictureListener {
if (mCapture == null) {
mCapture = Bitmap.createBitmap(mCaptureWidth, mCaptureHeight,
Bitmap.Config.RGB_565);
+ mCapture.eraseColor(Color.WHITE);
if (mInForeground) {
postCapture();
}
diff --git a/src/com/android/browser/UiController.java b/src/com/android/browser/UiController.java
index 14d498c..0da523a 100644
--- a/src/com/android/browser/UiController.java
+++ b/src/com/android/browser/UiController.java
@@ -98,4 +98,6 @@ public interface UiController {
void loadUrl(Tab tab, String url);
+ void setBlockEvents(boolean block);
+
}
diff --git a/src/com/android/browser/view/Gallery.java b/src/com/android/browser/view/Gallery.java
index 78d4bc6..2e2c75f 100644
--- a/src/com/android/browser/view/Gallery.java
+++ b/src/com/android/browser/view/Gallery.java
@@ -34,6 +34,8 @@ import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
+import android.view.animation.BounceInterpolator;
+import android.view.animation.DecelerateInterpolator;
import android.view.animation.Transformation;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
@@ -130,6 +132,8 @@ public class Gallery extends ViewGroup implements
private float mLastMotionCoord;
private float mLastOrthoCoord;
+ private int mScrollValue;
+
public Gallery(Context context) {
this(context, null);
}
@@ -172,6 +176,7 @@ public class Gallery extends ViewGroup implements
mGap = 0;
// proguard
setGap(getGap());
+ setScrollValue(getScrollValue());
}
/**
@@ -180,7 +185,10 @@ public class Gallery extends ViewGroup implements
*/
public interface OnItemSelectedListener {
void onItemSelected(ViewGroup parent, View view, int position, long id);
+ }
+ public interface OnScrollFinishedListener {
+ void onScrollFinished();
}
/**
@@ -226,6 +234,11 @@ public class Gallery extends ViewGroup implements
return mGap;
}
+ public void setAdapter(BaseAdapter adapter, int selpos) {
+ mSelectedPosition = selpos;
+ setAdapter(adapter);
+ }
+
public void setAdapter(BaseAdapter adapter) {
mAdapter = adapter;
if (mAdapter != null) {
@@ -246,7 +259,7 @@ public class Gallery extends ViewGroup implements
handleDataChanged();
}
- void handleDataChanged() {
+ public void handleDataChanged() {
if (mAdapter != null) {
if (mGapAnimator != null) {
mGapAnimator.cancel();
@@ -427,7 +440,8 @@ public class Gallery extends ViewGroup implements
return;
}
boolean toLeft = deltaX < 0;
- int limitedDeltaX = getLimitedMotionScrollAmount(toLeft, deltaX);
+ int limitedDeltaX = mFlingRunnable.mScroller.isFinished()
+ ? deltaX : getLimitedMotionScrollAmount(toLeft, deltaX);
if (limitedDeltaX != deltaX) {
// The above call returned a limited amount, so stop any
// scrolls/flings
@@ -1178,7 +1192,7 @@ public class Gallery extends ViewGroup implements
}
}
- boolean moveNext() {
+ public boolean moveNext() {
if (mItemCount > 0 && mSelectedPosition < mItemCount - 1) {
scrollToChild(mSelectedPosition - mFirstPosition + 1);
return true;
@@ -1187,16 +1201,48 @@ public class Gallery extends ViewGroup implements
}
}
- protected boolean scrollToChild(int childPosition) {
+ public boolean scrollToChild(int childPosition) {
View child = getChildAt(childPosition);
if (child != null) {
int distance = getCenterOfGallery() - getCenterOfView(child);
- mFlingRunnable.startUsingDistance(distance);
+ mFlingRunnable.startUsingDistance(distance, 0);
return true;
}
return false;
}
+ /**
+ * use the scroller to scroll to a new position, independent
+ * of whether attached or not
+ * this uses trackMotionScroll, which will set the selection
+ */
+ public void smoothScrollToPosition(int pos, int duration,
+ final OnScrollFinishedListener listener) {
+ if (pos >= mAdapter.getCount() || getChildCount() < 1) return;
+ int dist = (mSelectedPosition - pos) * (mHorizontal ? getChildHeight(getChildAt(0))
+ : getChildWidth(getChildAt(0)));
+ ObjectAnimator scroll = ObjectAnimator.ofInt(this, "scrollValue", 0, dist);
+ scroll.setDuration(duration);
+ scroll.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mScrollValue = 0;
+ listener.onScrollFinished();
+ }
+ });
+ scroll.setInterpolator(new BounceInterpolator());
+ scroll.start();
+ }
+
+ public void setScrollValue(int scroll) {
+ trackMotionScroll(scroll - mScrollValue);
+ mScrollValue = scroll;
+ }
+
+ public int getScrollValue() {
+ return mScrollValue;
+ }
+
protected void setSelectedPositionInt(int position) {
mSelectedPosition = position;
updateSelectedItemMetadata();
@@ -1368,11 +1414,15 @@ public class Gallery extends ViewGroup implements
}
public void startUsingDistance(int distance) {
+ startUsingDistance(distance, mAnimationDuration);
+ }
+
+ public void startUsingDistance(int distance, int duration) {
if (distance == 0)
return;
startCommon();
mLastFlingX = 0;
- mScroller.startScroll(0, 0, -distance, 0, mAnimationDuration);
+ mScroller.startScroll(0, 0, -distance, 0, duration);
post(this);
}