summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/PagedView.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/PagedView.java')
-rw-r--r--src/com/android/launcher3/PagedView.java1137
1 files changed, 287 insertions, 850 deletions
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 7d65f4686..218c1a36f 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -19,16 +19,16 @@ package com.android.launcher3;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Matrix;
-import android.graphics.PointF;
import android.graphics.Rect;
+import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -46,20 +46,12 @@ import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.animation.AnimationUtils;
-import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import java.util.ArrayList;
+import com.android.launcher3.util.LauncherEdgeEffect;
+import com.android.launcher3.util.Thunk;
-interface Page {
- public int getPageChildCount();
- public View getChildOnPageAt(int i);
- public void removeAllViewsOnPage();
- public void removeViewOnPageAt(int i);
- public int indexOfChildOnPage(View v);
-}
+import java.util.ArrayList;
/**
* An abstraction of the original Workspace which supports browsing through a
@@ -74,28 +66,21 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private static final int MIN_LENGTH_FOR_FLING = 25;
protected static final int PAGE_SNAP_ANIMATION_DURATION = 750;
- protected static final int OVER_SCROLL_PAGE_SNAP_ANIMATION_DURATION = 350;
protected static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950;
protected static final float NANOTIME_DIV = 1000000000.0f;
- private static final float OVERSCROLL_ACCELERATE_FACTOR = 2;
- private static final float OVERSCROLL_DAMP_FACTOR = 0.07f;
-
private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f;
// The page is moved more than halfway, automatically move to the next page on touch up.
private static final float SIGNIFICANT_MOVE_THRESHOLD = 0.4f;
+ private static final float MAX_SCROLL_PROGRESS = 1.0f;
+
// The following constants need to be scaled based on density. The scaled versions will be
// assigned to the corresponding member variables below.
private static final int FLING_THRESHOLD_VELOCITY = 500;
private static final int MIN_SNAP_VELOCITY = 1500;
private static final int MIN_FLING_VELOCITY = 250;
- // We are disabling touch interaction of the widget region for factory ROM.
- private static final boolean DISABLE_TOUCH_INTERACTION = false;
- private static final boolean DISABLE_TOUCH_SIDE_PAGES = true;
- private static final boolean DISABLE_FLING_TO_DELETE = true;
-
public static final int INVALID_RESTORE_PAGE = -1001;
private boolean mFreeScroll = false;
@@ -124,7 +109,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected LauncherScroller mScroller;
private Interpolator mDefaultInterpolator;
private VelocityTracker mVelocityTracker;
- private int mPageSpacing = 0;
+ @Thunk int mPageSpacing = 0;
private float mParentDownMotionX;
private float mParentDownMotionY;
@@ -156,7 +141,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected OnLongClickListener mLongClickListener;
protected int mTouchSlop;
- private int mPagingTouchSlop;
private int mMaximumVelocity;
protected int mPageLayoutWidthGap;
protected int mPageLayoutHeightGap;
@@ -164,15 +148,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected int mCellCountY = 0;
protected boolean mCenterPagesVertically;
protected boolean mAllowOverScroll = true;
- protected int mUnboundedScrollX;
protected int[] mTempVisiblePagesRange = new int[2];
protected boolean mForceDrawAllChildrenNextFrame;
- private boolean mSpacePagesAutomatically = false;
-
- // mOverScrollX is equal to getScrollX() when we're within the normal scroll range. Otherwise
- // it is equal to the scaled overscroll position. We use a separate value so as to prevent
- // the screens from continuing to translate beyond the normal bounds.
- protected int mOverScrollX;
protected static final int INVALID_POINTER = -1;
@@ -180,37 +157,16 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private PageSwitchListener mPageSwitchListener;
- protected ArrayList<Boolean> mDirtyPageContent;
-
- // If true, syncPages and syncPageItems will be called to refresh pages
- protected boolean mContentIsRefreshable = true;
-
// If true, modify alpha of neighboring pages as user scrolls left/right
protected boolean mFadeInAdjacentScreens = false;
- // It true, use a different slop parameter (pagingTouchSlop = 2 * touchSlop) for deciding
- // to switch to a new page
- protected boolean mUsePagingTouchSlop = true;
-
- // If true, the subclass should directly update scrollX itself in its computeScroll method
- // (SmoothPagedView does this)
- protected boolean mDeferScrollUpdate = false;
- protected boolean mDeferLoadAssociatedPagesUntilScrollCompletes = false;
-
protected boolean mIsPageMoving = false;
- // All syncs and layout passes are deferred until data is ready.
- protected boolean mIsDataReady = false;
-
- protected boolean mAllowLongPress = true;
-
private boolean mWasInOverscroll = false;
// Page Indicator
- private int mPageIndicatorViewId;
- private PageIndicator mPageIndicator;
- private boolean mAllowPagedViewAnimations = true;
-
+ @Thunk int mPageIndicatorViewId;
+ @Thunk PageIndicator mPageIndicator;
// The viewport whether the pages are to be contained (the actual view may be larger than the
// viewport)
private Rect mViewport = new Rect();
@@ -218,16 +174,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Reordering
// We use the min scale to determine how much to expand the actually PagedView measured
// dimensions such that when we are zoomed out, the view is not clipped
- private int REORDERING_DROP_REPOSITION_DURATION = 200;
- protected int REORDERING_REORDER_REPOSITION_DURATION = 300;
- protected int REORDERING_ZOOM_IN_OUT_DURATION = 250;
- private int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 80;
+ private static int REORDERING_DROP_REPOSITION_DURATION = 200;
+ @Thunk static int REORDERING_REORDER_REPOSITION_DURATION = 300;
+ private static int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 80;
+
private float mMinScale = 1f;
private boolean mUseMinScale = false;
protected View mDragView;
- protected AnimatorSet mZoomInOutAnim;
private Runnable mSidePageHoverRunnable;
- private int mSidePageHoverIndex = -1;
+ @Thunk int mSidePageHoverIndex = -1;
// This variable's scope is only for the duration of startReordering() and endReordering()
private boolean mReorderingStarted = false;
// This variable's scope is for the duration of startReordering() and after the zoomIn()
@@ -239,30 +194,17 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private Runnable mPostReorderingPreZoomInRunnable;
// Convenience/caching
- private Matrix mTmpInvMatrix = new Matrix();
- private float[] mTmpPoint = new float[2];
- private int[] mTmpIntPoint = new int[2];
- private Rect mTmpRect = new Rect();
- private Rect mAltTmpRect = new Rect();
-
- // Fling to delete
- private int FLING_TO_DELETE_FADE_OUT_DURATION = 350;
- private float FLING_TO_DELETE_FRICTION = 0.035f;
- // The degrees specifies how much deviation from the up vector to still consider a fling "up"
- private float FLING_TO_DELETE_MAX_FLING_DEGREES = 65f;
- protected int mFlingToDeleteThresholdVelocity = -1400;
- // Drag to delete
- private boolean mDeferringForDelete = false;
- private int DELETE_SLIDE_IN_SIDE_PAGE_DURATION = 250;
- private int DRAG_TO_DELETE_FADE_OUT_DURATION = 350;
-
- // Drop to delete
- private View mDeleteDropTarget;
-
- // Bouncer
- private boolean mTopAlignPageWhenShrinkingForBouncer = false;
+ private static final Matrix sTmpInvMatrix = new Matrix();
+ private static final float[] sTmpPoint = new float[2];
+ private static final int[] sTmpIntPoint = new int[2];
+ private static final Rect sTmpRect = new Rect();
protected final Rect mInsets = new Rect();
+ protected final boolean mIsRtl;
+
+ // Edge effect
+ private final LauncherEdgeEffect mEdgeGlowLeft = new LauncherEdgeEffect();
+ private final LauncherEdgeEffect mEdgeGlowRight = new LauncherEdgeEffect();
public interface PageSwitchListener {
void onPageSwitch(View newPage, int newPageIndex);
@@ -290,6 +232,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
a.recycle();
setHapticFeedbackEnabled(false);
+ mIsRtl = Utilities.isRtl(getResources());
init();
}
@@ -297,8 +240,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
* Initializes various states for this workspace.
*/
protected void init() {
- mDirtyPageContent = new ArrayList<Boolean>();
- mDirtyPageContent.ensureCapacity(32);
mScroller = new LauncherScroller(getContext());
setDefaultInterpolator(new ScrollInterpolator());
mCurrentPage = 0;
@@ -306,18 +247,19 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mTouchSlop = configuration.getScaledPagingTouchSlop();
- mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mDensity = getResources().getDisplayMetrics().density;
- // Scale the fling-to-delete threshold by the density
- mFlingToDeleteThresholdVelocity =
- (int) (mFlingToDeleteThresholdVelocity * mDensity);
-
mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
mMinFlingVelocity = (int) (MIN_FLING_VELOCITY * mDensity);
mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * mDensity);
setOnHierarchyChangeListener(this);
+ setWillNotDraw(false);
+ }
+
+ protected void setEdgeGlowColor(int color) {
+ mEdgeGlowLeft.setColor(color);
+ mEdgeGlowRight.setColor(color);
}
protected void setDefaultInterpolator(Interpolator interpolator) {
@@ -333,7 +275,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
ViewGroup grandParent = (ViewGroup) parent.getParent();
if (mPageIndicator == null && mPageIndicatorViewId > -1) {
mPageIndicator = (PageIndicator) grandParent.findViewById(mPageIndicatorViewId);
- mPageIndicator.removeAllMarkers(mAllowPagedViewAnimations);
+ mPageIndicator.removeAllMarkers(true);
ArrayList<PageIndicator.PageMarkerResources> markers =
new ArrayList<PageIndicator.PageMarkerResources>();
@@ -341,7 +283,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
markers.add(getPageIndicatorMarker(i));
}
- mPageIndicator.addMarkers(markers, mAllowPagedViewAnimations);
+ mPageIndicator.addMarkers(markers, true);
OnClickListener listener = getPageIndicatorClickListener();
if (listener != null) {
@@ -359,33 +301,31 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return null;
}
+ @Override
protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
// Unhook the page indicator
mPageIndicator = null;
}
- void setDeleteDropTarget(View v) {
- mDeleteDropTarget = v;
- }
-
// Convenience methods to map points from self to parent and vice versa
- float[] mapPointFromViewToParent(View v, float x, float y) {
- mTmpPoint[0] = x;
- mTmpPoint[1] = y;
- v.getMatrix().mapPoints(mTmpPoint);
- mTmpPoint[0] += v.getLeft();
- mTmpPoint[1] += v.getTop();
- return mTmpPoint;
- }
- float[] mapPointFromParentToView(View v, float x, float y) {
- mTmpPoint[0] = x - v.getLeft();
- mTmpPoint[1] = y - v.getTop();
- v.getMatrix().invert(mTmpInvMatrix);
- mTmpInvMatrix.mapPoints(mTmpPoint);
- return mTmpPoint;
- }
-
- void updateDragViewTranslationDuringDrag() {
+ private float[] mapPointFromViewToParent(View v, float x, float y) {
+ sTmpPoint[0] = x;
+ sTmpPoint[1] = y;
+ v.getMatrix().mapPoints(sTmpPoint);
+ sTmpPoint[0] += v.getLeft();
+ sTmpPoint[1] += v.getTop();
+ return sTmpPoint;
+ }
+ private float[] mapPointFromParentToView(View v, float x, float y) {
+ sTmpPoint[0] = x - v.getLeft();
+ sTmpPoint[1] = y - v.getTop();
+ v.getMatrix().invert(sTmpInvMatrix);
+ sTmpInvMatrix.mapPoints(sTmpPoint);
+ return sTmpPoint;
+ }
+
+ private void updateDragViewTranslationDuringDrag() {
if (mDragView != null) {
float x = (mLastMotionX - mDownMotionX) + (getScrollX() - mDownScrollX) +
(mDragViewBaselineLeft - mDragView.getLeft());
@@ -453,33 +393,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
/**
- * Note: this is a reimplementation of View.isLayoutRtl() since that is currently hidden api.
- */
- public boolean isLayoutRtl() {
- return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
- }
-
- /**
- * Called by subclasses to mark that data is ready, and that we can begin loading and laying
- * out pages.
- */
- protected void setDataIsReady() {
- mIsDataReady = true;
- }
-
- protected boolean isDataReady() {
- return mIsDataReady;
- }
-
- /**
* Returns the index of the currently displayed page.
- *
- * @return The index of the currently displayed page.
*/
- int getCurrentPage() {
+ public int getCurrentPage() {
return mCurrentPage;
}
+ /**
+ * Returns the index of page to be shown immediately afterwards.
+ */
int getNextPage() {
return (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
}
@@ -488,7 +410,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return getChildCount();
}
- View getPageAt(int index) {
+ public View getPageAt(int index) {
return getChildAt(index);
}
@@ -512,17 +434,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
forceFinishScroller();
}
- /**
- * Called during AllApps/Home transitions to avoid unnecessary work. When that other animation
- * {@link #updateCurrentPageScroll()} should be called, to correctly set the final state and
- * re-enable scrolling.
- */
- void stopScrolling() {
- mCurrentPage = getNextPage();
- notifyPageSwitchListener();
- forceFinishScroller();
- }
-
private void abortScrollerAnimation(boolean resetNextPage) {
mScroller.abortAnimation();
// We need to clean up the next page here to avoid computeScrollHelper from
@@ -555,7 +466,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
/**
* Sets the current page.
*/
- void setCurrentPage(int currentPage) {
+ public void setCurrentPage(int currentPage) {
if (!mScroller.isFinished()) {
abortScrollerAnimation(true);
}
@@ -647,37 +558,41 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
@Override
public void scrollBy(int x, int y) {
- scrollTo(mUnboundedScrollX + x, getScrollY() + y);
+ scrollTo(getScrollX() + x, getScrollY() + y);
}
@Override
public void scrollTo(int x, int y) {
// In free scroll mode, we clamp the scrollX
if (mFreeScroll) {
+ // If the scroller is trying to move to a location beyond the maximum allowed
+ // in the free scroll mode, we make sure to end the scroll operation.
+ if (!mScroller.isFinished() &&
+ (x > mFreeScrollMaxScrollX || x < mFreeScrollMinScrollX)) {
+ forceFinishScroller();
+ }
+
x = Math.min(x, mFreeScrollMaxScrollX);
x = Math.max(x, mFreeScrollMinScrollX);
}
- final boolean isRtl = isLayoutRtl();
- mUnboundedScrollX = x;
-
- boolean isXBeforeFirstPage = isRtl ? (x > mMaxScrollX) : (x < 0);
- boolean isXAfterLastPage = isRtl ? (x < 0) : (x > mMaxScrollX);
+ boolean isXBeforeFirstPage = mIsRtl ? (x > mMaxScrollX) : (x < 0);
+ boolean isXAfterLastPage = mIsRtl ? (x < 0) : (x > mMaxScrollX);
if (isXBeforeFirstPage) {
- super.scrollTo(0, y);
+ super.scrollTo(mIsRtl ? mMaxScrollX : 0, y);
if (mAllowOverScroll) {
mWasInOverscroll = true;
- if (isRtl) {
+ if (mIsRtl) {
overScroll(x - mMaxScrollX);
} else {
overScroll(x);
}
}
} else if (isXAfterLastPage) {
- super.scrollTo(mMaxScrollX, y);
+ super.scrollTo(mIsRtl ? 0 : mMaxScrollX, y);
if (mAllowOverScroll) {
mWasInOverscroll = true;
- if (isRtl) {
+ if (mIsRtl) {
overScroll(x);
} else {
overScroll(x - mMaxScrollX);
@@ -688,7 +603,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
overScroll(0);
mWasInOverscroll = false;
}
- mOverScrollX = x;
super.scrollTo(x, y);
}
@@ -708,21 +622,17 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
AccessibilityManager am =
(AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
if (am.isEnabled()) {
- AccessibilityEvent ev =
- AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_SCROLLED);
- ev.setItemCount(getChildCount());
- ev.setFromIndex(mCurrentPage);
- ev.setToIndex(getNextPage());
-
- final int action;
- if (getNextPage() >= mCurrentPage) {
- action = AccessibilityNodeInfo.ACTION_SCROLL_FORWARD;
- } else {
- action = AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD;
+ if (mCurrentPage != getNextPage()) {
+ AccessibilityEvent ev =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_SCROLLED);
+ ev.setScrollable(true);
+ ev.setScrollX(getScrollX());
+ ev.setScrollY(getScrollY());
+ ev.setMaxScrollX(mMaxScrollX);
+ ev.setMaxScrollY(0);
+
+ sendAccessibilityEventUnchecked(ev);
}
-
- ev.setAction(action);
- sendAccessibilityEventUnchecked(ev);
}
}
@@ -731,8 +641,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (mScroller.computeScrollOffset()) {
// Don't bother scrolling if the page does not need to be moved
if (getScrollX() != mScroller.getCurrX()
- || getScrollY() != mScroller.getCurrY()
- || mOverScrollX != mScroller.getCurrX()) {
+ || getScrollY() != mScroller.getCurrY()) {
float scaleX = mFreeScroll ? getScaleX() : 1f;
int scrollX = (int) (mScroller.getCurrX() * (1 / scaleX));
scrollTo(scrollX, mScroller.getCurrY());
@@ -746,12 +655,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mNextPage = INVALID_PAGE;
notifyPageSwitchListener();
- // Load the associated pages if necessary
- if (mDeferLoadAssociatedPagesUntilScrollCompletes) {
- loadAssociatedPages(mCurrentPage);
- mDeferLoadAssociatedPagesUntilScrollCompletes = false;
- }
-
// We don't want to trigger a page end moving unless the page has settled
// and the user has stopped scrolling
if (mTouchState == TOUCH_STATE_REST) {
@@ -775,10 +678,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
computeScrollHelper();
}
- protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
- return mTopAlignPageWhenShrinkingForBouncer;
- }
-
public static class LayoutParams extends ViewGroup.LayoutParams {
public boolean isFullScreenPage = false;
@@ -789,15 +688,35 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
super(width, height);
}
+ public LayoutParams(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
}
+ @Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
+ }
+
+ @Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return new LayoutParams(p);
+ }
+
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams;
+ }
+
public void addFullScreenPage(View page) {
LayoutParams lp = generateDefaultLayoutParams();
lp.isFullScreenPage = true;
@@ -810,7 +729,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- if (!mIsDataReady || getChildCount() == 0) {
+ if (getChildCount() == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
@@ -914,27 +833,12 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
- if (mSpacePagesAutomatically) {
- int spacing = (getViewportWidth() - mInsets.left - mInsets.right
- - referenceChildWidth) / 2;
- if (spacing >= 0) {
- setPageSpacing(spacing);
- }
- mSpacePagesAutomatically = false;
- }
setMeasuredDimension(scaledWidthSize, scaledHeightSize);
}
- /**
- * This method should be called once before first layout / measure pass.
- */
- protected void setSinglePageInViewport() {
- mSpacePagesAutomatically = true;
- }
-
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- if (!mIsDataReady || getChildCount() == 0) {
+ if (getChildCount() == 0) {
return;
}
@@ -945,13 +849,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
int offsetY = getViewportOffsetY();
// Update the viewport offsets
- mViewport.offset(offsetX, offsetY);
-
- final boolean isRtl = isLayoutRtl();
+ mViewport.offset(offsetX, offsetY);
- final int startIndex = isRtl ? childCount - 1 : 0;
- final int endIndex = isRtl ? -1 : childCount;
- final int delta = isRtl ? -1 : 1;
+ final int startIndex = mIsRtl ? childCount - 1 : 0;
+ final int endIndex = mIsRtl ? -1 : childCount;
+ final int delta = mIsRtl ? -1 : 1;
int verticalPadding = getPaddingTop() + getPaddingBottom();
@@ -959,8 +861,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
LayoutParams nextLp;
int childLeft = offsetX + (lp.isFullScreenPage ? 0 : getPaddingLeft());
- if (mPageScrolls == null || getChildCount() != mChildCountOnLastLayout) {
- mPageScrolls = new int[getChildCount()];
+ if (mPageScrolls == null || childCount != mChildCountOnLastLayout) {
+ mPageScrolls = new int[childCount];
}
for (int i = startIndex; i != endIndex; i += delta) {
@@ -1003,24 +905,40 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
pageGap = getPaddingRight();
}
- childLeft += childWidth + pageGap;
+ childLeft += childWidth + pageGap + getChildGap();
}
}
- if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
- updateCurrentPageScroll();
- mFirstLayout = false;
- }
+ final LayoutTransition transition = getLayoutTransition();
+ // If the transition is running defer updating max scroll, as some empty pages could
+ // still be present, and a max scroll change could cause sudden jumps in scroll.
+ if (transition != null && transition.isRunning()) {
+ transition.addTransitionListener(new LayoutTransition.TransitionListener() {
- if (childCount > 0) {
- final int index = isLayoutRtl() ? 0 : childCount - 1;
- mMaxScrollX = getScrollForPage(index);
+ @Override
+ public void startTransition(LayoutTransition transition, ViewGroup container,
+ View view, int transitionType) { }
+
+ @Override
+ public void endTransition(LayoutTransition transition, ViewGroup container,
+ View view, int transitionType) {
+ // Wait until all transitions are complete.
+ if (!transition.isRunning()) {
+ transition.removeTransitionListener(this);
+ updateMaxScrollX();
+ }
+ }
+ });
} else {
- mMaxScrollX = 0;
+ updateMaxScrollX();
}
- if (mScroller.isFinished() && mChildCountOnLastLayout != getChildCount() &&
- !mDeferringForDelete) {
+ if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < childCount) {
+ updateCurrentPageScroll();
+ mFirstLayout = false;
+ }
+
+ if (mScroller.isFinished() && mChildCountOnLastLayout != childCount) {
if (mRestorePage != INVALID_RESTORE_PAGE) {
setCurrentPage(mRestorePage);
mRestorePage = INVALID_RESTORE_PAGE;
@@ -1028,42 +946,37 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
setCurrentPage(getNextPage());
}
}
- mChildCountOnLastLayout = getChildCount();
+ mChildCountOnLastLayout = childCount;
if (isReordering(true)) {
updateDragViewTranslationDuringDrag();
}
}
- public void setPageSpacing(int pageSpacing) {
- mPageSpacing = pageSpacing;
- requestLayout();
+ protected int getChildGap() {
+ return 0;
}
- protected void screenScrolled(int screenCenter) {
- boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX;
-
- if (mFadeInAdjacentScreens && !isInOverscroll) {
- for (int i = 0; i < getChildCount(); i++) {
- View child = getChildAt(i);
- if (child != null) {
- float scrollProgress = getScrollProgress(screenCenter, child, i);
- float alpha = 1 - Math.abs(scrollProgress);
- child.setAlpha(alpha);
- }
- }
- invalidate();
+ @Thunk void updateMaxScrollX() {
+ int childCount = getChildCount();
+ if (childCount > 0) {
+ final int index = mIsRtl ? 0 : childCount - 1;
+ mMaxScrollX = getScrollForPage(index);
+ } else {
+ mMaxScrollX = 0;
}
}
- protected void enablePagedViewAnimations() {
- mAllowPagedViewAnimations = true;
-
- }
- protected void disablePagedViewAnimations() {
- mAllowPagedViewAnimations = false;
+ public void setPageSpacing(int pageSpacing) {
+ mPageSpacing = pageSpacing;
+ requestLayout();
}
+ /**
+ * Called when the center screen changes during scrolling.
+ */
+ protected void screenScrolled(int screenCenter) { }
+
@Override
public void onChildViewAdded(View parent, View child) {
// Update the page indicator, we don't update the page indicator as we
@@ -1072,7 +985,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
int pageIndex = indexOfChild(child);
mPageIndicator.addMarker(pageIndex,
getPageIndicatorMarker(pageIndex),
- mAllowPagedViewAnimations);
+ true);
}
// This ensures that when children are added, they get the correct transforms / alphas
@@ -1093,7 +1006,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Update the page indicator, we don't update the page indicator as we
// add/remove pages
if (mPageIndicator != null && !isReordering(false)) {
- mPageIndicator.removeMarker(index, mAllowPagedViewAnimations);
+ mPageIndicator.removeMarker(index, true);
}
}
@@ -1115,7 +1028,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
public void removeViewAt(int index) {
// XXX: We should find a better way to hook into this before the view
// gets removed form its parent...
- removeViewAt(index);
+ removeMarkerForView(index);
super.removeViewAt(index);
}
@Override
@@ -1123,7 +1036,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Update the page indicator, we don't update the page indicator as we
// add/remove pages
if (mPageIndicator != null) {
- mPageIndicator.removeAllMarkers(mAllowPagedViewAnimations);
+ mPageIndicator.removeAllMarkers(true);
}
super.removeAllViewsInLayout();
@@ -1144,7 +1057,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected void getVisiblePages(int[] range) {
final int pageCount = getChildCount();
- mTmpIntPoint[0] = mTmpIntPoint[1] = 0;
+ sTmpIntPoint[0] = sTmpIntPoint[1] = 0;
range[0] = -1;
range[1] = -1;
@@ -1157,9 +1070,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
for (int i = 0; i < count; i++) {
View currPage = getPageAt(i);
- mTmpIntPoint[0] = 0;
- Utilities.getDescendantCoordRelativeToParent(currPage, this, mTmpIntPoint, false);
- if (mTmpIntPoint[0] > viewportWidth) {
+ sTmpIntPoint[0] = 0;
+ Utilities.getDescendantCoordRelativeToParent(currPage, this, sTmpIntPoint, false);
+ if (sTmpIntPoint[0] > viewportWidth) {
if (range[0] == -1) {
continue;
} else {
@@ -1167,9 +1080,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
- mTmpIntPoint[0] = currPage.getMeasuredWidth();
- Utilities.getDescendantCoordRelativeToParent(currPage, this, mTmpIntPoint, false);
- if (mTmpIntPoint[0] < 0) {
+ sTmpIntPoint[0] = currPage.getMeasuredWidth();
+ Utilities.getDescendantCoordRelativeToParent(currPage, this, sTmpIntPoint, false);
+ if (sTmpIntPoint[0] < 0) {
if (range[0] == -1) {
continue;
} else {
@@ -1199,9 +1112,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final int pageCount = getChildCount();
if (pageCount > 0) {
int halfScreenSize = getViewportWidth() / 2;
- // mOverScrollX is equal to getScrollX() when we're within the normal scroll range.
- // Otherwise it is equal to the scaled overscroll position.
- int screenCenter = mOverScrollX + halfScreenSize;
+ int screenCenter = getScrollX() + halfScreenSize;
if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
// set mForceScreenScrolled before calling screenScrolled so that screenScrolled can
@@ -1242,6 +1153,46 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
@Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ if (getPageCount() > 0) {
+ if (!mEdgeGlowLeft.isFinished()) {
+ final int restoreCount = canvas.save();
+ Rect display = mViewport;
+ canvas.translate(display.left, display.top);
+ canvas.rotate(270);
+
+ getEdgeVerticalPostion(sTmpIntPoint);
+ canvas.translate(display.top - sTmpIntPoint[1], 0);
+ mEdgeGlowLeft.setSize(sTmpIntPoint[1] - sTmpIntPoint[0], display.width());
+ if (mEdgeGlowLeft.draw(canvas)) {
+ postInvalidateOnAnimation();
+ }
+ canvas.restoreToCount(restoreCount);
+ }
+ if (!mEdgeGlowRight.isFinished()) {
+ final int restoreCount = canvas.save();
+ Rect display = mViewport;
+ canvas.translate(display.left + mPageScrolls[mIsRtl ? 0 : (getPageCount() - 1)], display.top);
+ canvas.rotate(90);
+
+ getEdgeVerticalPostion(sTmpIntPoint);
+ canvas.translate(sTmpIntPoint[0] - display.top, -display.width());
+ mEdgeGlowRight.setSize(sTmpIntPoint[1] - sTmpIntPoint[0], display.width());
+ if (mEdgeGlowRight.draw(canvas)) {
+ postInvalidateOnAnimation();
+ }
+ canvas.restoreToCount(restoreCount);
+ }
+ }
+ }
+
+ /**
+ * Returns the top and bottom position for the edge effect.
+ */
+ protected abstract void getEdgeVerticalPostion(int[] pos);
+
+ @Override
public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
int page = indexToPage(indexOfChild(child));
if (page != mCurrentPage || !mScroller.isFinished()) {
@@ -1346,7 +1297,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
* Return true if a tap at (x, y) should trigger a flip to the previous page.
*/
protected boolean hitsPreviousPage(float x, float y) {
- if (isLayoutRtl()) {
+ if (mIsRtl) {
return (x > (getViewportOffsetX() + getViewportWidth() -
getPaddingRight() - mPageSpacing));
}
@@ -1357,7 +1308,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
* Return true if a tap at (x, y) should trigger a flip to the next page.
*/
protected boolean hitsNextPage(float x, float y) {
- if (isLayoutRtl()) {
+ if (mIsRtl) {
return (x < getViewportOffsetX() + getPaddingLeft() + mPageSpacing);
}
return (x > (getViewportOffsetX() + getViewportWidth() -
@@ -1366,17 +1317,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
/** Returns whether x and y originated within the buffered viewport */
private boolean isTouchPointInViewportWithBuffer(int x, int y) {
- mTmpRect.set(mViewport.left - mViewport.width() / 2, mViewport.top,
+ sTmpRect.set(mViewport.left - mViewport.width() / 2, mViewport.top,
mViewport.right + mViewport.width() / 2, mViewport.bottom);
- return mTmpRect.contains(x, y);
+ return sTmpRect.contains(x, y);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (DISABLE_TOUCH_INTERACTION) {
- return false;
- }
-
/*
* This method JUST determines whether we want to intercept the motion.
* If we return true, onTouchEvent will be called and we do the actual
@@ -1453,19 +1400,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
- // check if this can be the beginning of a tap on the side of the pages
- // to scroll the current page
- if (!DISABLE_TOUCH_SIDE_PAGES) {
- if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) {
- if (getChildCount() > 0) {
- if (hitsPreviousPage(x, y)) {
- mTouchState = TOUCH_STATE_PREV_PAGE;
- } else if (hitsNextPage(x, y)) {
- mTouchState = TOUCH_STATE_NEXT_PAGE;
- }
- }
- }
- }
break;
}
@@ -1506,54 +1440,33 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (!isTouchPointInViewportWithBuffer((int) x, (int) y)) return;
final int xDiff = (int) Math.abs(x - mLastMotionX);
- final int yDiff = (int) Math.abs(y - mLastMotionY);
final int touchSlop = Math.round(touchSlopScale * mTouchSlop);
- boolean xPaged = xDiff > mPagingTouchSlop;
boolean xMoved = xDiff > touchSlop;
- boolean yMoved = yDiff > touchSlop;
- if (xMoved || xPaged || yMoved) {
- if (mUsePagingTouchSlop ? xPaged : xMoved) {
- // Scroll if the user moved far enough along the X axis
- mTouchState = TOUCH_STATE_SCROLLING;
- mTotalMotionX += Math.abs(mLastMotionX - x);
- mLastMotionX = x;
- mLastMotionXRemainder = 0;
- mTouchX = getViewportOffsetX() + getScrollX();
- mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
- onScrollInteractionBegin();
- pageBeginMoving();
- }
+ if (xMoved) {
+ // Scroll if the user moved far enough along the X axis
+ mTouchState = TOUCH_STATE_SCROLLING;
+ mTotalMotionX += Math.abs(mLastMotionX - x);
+ mLastMotionX = x;
+ mLastMotionXRemainder = 0;
+ mTouchX = getViewportOffsetX() + getScrollX();
+ mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+ onScrollInteractionBegin();
+ pageBeginMoving();
}
}
- protected float getMaxScrollProgress() {
- return 1.0f;
- }
-
protected void cancelCurrentPageLongPress() {
- if (mAllowLongPress) {
- //mAllowLongPress = false;
- // Try canceling the long press. It could also have been scheduled
- // by a distant descendant, so use the mAllowLongPress flag to block
- // everything
- final View currentPage = getPageAt(mCurrentPage);
- if (currentPage != null) {
- currentPage.cancelLongPress();
- }
+ // Try canceling the long press. It could also have been scheduled
+ // by a distant descendant, so use the mAllowLongPress flag to block
+ // everything
+ final View currentPage = getPageAt(mCurrentPage);
+ if (currentPage != null) {
+ currentPage.cancelLongPress();
}
}
- protected float getBoundedScrollProgress(int screenCenter, View v, int page) {
- final int halfScreenSize = getViewportWidth() / 2;
-
- screenCenter = Math.min(getScrollX() + halfScreenSize, screenCenter);
- screenCenter = Math.max(halfScreenSize, screenCenter);
-
- return getScrollProgress(screenCenter, v, page);
- }
-
protected float getScrollProgress(int screenCenter, View v, int page) {
final int halfScreenSize = getViewportWidth() / 2;
@@ -1563,7 +1476,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final int totalDistance;
int adjacentPage = page + 1;
- if ((delta < 0 && !isLayoutRtl()) || (delta > 0 && isLayoutRtl())) {
+ if ((delta < 0 && !mIsRtl) || (delta > 0 && mIsRtl)) {
adjacentPage = page - 1;
}
@@ -1574,8 +1487,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
float scrollProgress = delta / (totalDistance * 1.0f);
- scrollProgress = Math.min(scrollProgress, getMaxScrollProgress());
- scrollProgress = Math.max(scrollProgress, - getMaxScrollProgress());
+ scrollProgress = Math.min(scrollProgress, MAX_SCROLL_PROGRESS);
+ scrollProgress = Math.max(scrollProgress, - MAX_SCROLL_PROGRESS);
return scrollProgress;
}
@@ -1598,7 +1511,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
int scrollOffset = 0;
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (!lp.isFullScreenPage) {
- scrollOffset = isLayoutRtl() ? getPaddingRight() : getPaddingLeft();
+ scrollOffset = mIsRtl ? getPaddingRight() : getPaddingLeft();
}
int baselineX = mPageScrolls[index] + scrollOffset + getViewportOffsetX();
@@ -1606,49 +1519,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
- // This curve determines how the effect of scrolling over the limits of the page dimishes
- // as the user pulls further and further from the bounds
- private float overScrollInfluenceCurve(float f) {
- f -= 1.0f;
- return f * f * f + 1.0f;
- }
-
- protected float acceleratedOverFactor(float amount) {
- int screenSize = getViewportWidth();
-
- // We want to reach the max over scroll effect when the user has
- // over scrolled half the size of the screen
- float f = OVERSCROLL_ACCELERATE_FACTOR * (amount / screenSize);
-
- if (f == 0) return 0;
-
- // Clamp this factor, f, to -1 < f < 1
- if (Math.abs(f) >= 1) {
- f /= Math.abs(f);
- }
- return f;
- }
-
protected void dampedOverScroll(float amount) {
int screenSize = getViewportWidth();
-
float f = (amount / screenSize);
-
- if (f == 0) return;
- f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
-
- // Clamp this factor, f, to -1 < f < 1
- if (Math.abs(f) >= 1) {
- f /= Math.abs(f);
- }
-
- int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
- if (amount < 0) {
- mOverScrollX = overScrollAmount;
- super.scrollTo(mOverScrollX, getScrollY());
+ if (f < 0) {
+ mEdgeGlowLeft.onPull(-f);
+ } else if (f > 0) {
+ mEdgeGlowRight.onPull(f);
} else {
- mOverScrollX = mMaxScrollX + overScrollAmount;
- super.scrollTo(mOverScrollX, getScrollY());
+ return;
}
invalidate();
}
@@ -1657,25 +1536,17 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
dampedOverScroll(amount);
}
- protected float maxOverScroll() {
- // Using the formula in overScroll, assuming that f = 1.0 (which it should generally not
- // exceed). Used to find out how much extra wallpaper we need for the over scroll effect
- float f = 1.0f;
- f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
- return OVERSCROLL_DAMP_FACTOR * f;
- }
-
- protected void enableFreeScroll() {
+ public void enableFreeScroll() {
setEnableFreeScroll(true);
}
- protected void disableFreeScroll() {
+ public void disableFreeScroll() {
setEnableFreeScroll(false);
}
void updateFreescrollBounds() {
getFreeScrollPageRange(mTempVisiblePagesRange);
- if (isLayoutRtl()) {
+ if (mIsRtl) {
mFreeScrollMinScrollX = getScrollForPage(mTempVisiblePagesRange[1]);
mFreeScrollMaxScrollX = getScrollForPage(mTempVisiblePagesRange[0]);
} else {
@@ -1700,11 +1571,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
setEnableOverscroll(!freeScroll);
}
- private void setEnableOverscroll(boolean enable) {
+ protected void setEnableOverscroll(boolean enable) {
mAllowOverScroll = enable;
}
- int getNearestHoverOverPageIndex() {
+ private int getNearestHoverOverPageIndex() {
if (mDragView != null) {
int dragX = (int) (mDragView.getLeft() + (mDragView.getMeasuredWidth() / 2)
+ mDragView.getTranslationX());
@@ -1727,10 +1598,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
@Override
public boolean onTouchEvent(MotionEvent ev) {
- if (DISABLE_TOUCH_INTERACTION) {
- return false;
- }
-
super.onTouchEvent(ev);
// Skip touch handling if there are no pages to swipe
@@ -1785,12 +1652,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (Math.abs(deltaX) >= 1.0f) {
mTouchX += deltaX;
mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
- if (!mDeferScrollUpdate) {
- scrollBy((int) deltaX, 0);
- if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
- } else {
- invalidate();
- }
+ scrollBy((int) deltaX, 0);
mLastMotionX = x;
mLastMotionXRemainder = deltaX - (int) deltaX;
} else {
@@ -1811,19 +1673,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Find the closest page to the touch point
final int dragViewIndex = indexOfChild(mDragView);
- // Change the drag view if we are hovering over the drop target
- boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget(
- (int) mParentDownMotionX, (int) mParentDownMotionY);
- setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);
-
if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX);
if (DEBUG) Log.d(TAG, "mLastMotionY: " + mLastMotionY);
if (DEBUG) Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
if (DEBUG) Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);
final int pageUnderPointIndex = getNearestHoverOverPageIndex();
- if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView) &&
- !isHoveringOverDelete) {
+ if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView)) {
mTempVisiblePagesRange[0] = 0;
mTempVisiblePagesRange[1] = getPageCount() - 1;
getFreeScrollPageRange(mTempVisiblePagesRange);
@@ -1870,9 +1726,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
removeView(mDragView);
- onRemoveView(mDragView, false);
addView(mDragView, pageUnderPointIndex);
- onAddView(mDragView, pageUnderPointIndex);
mSidePageHoverIndex = -1;
if (mPageIndicator != null) {
mPageIndicator.setActiveMarker(getNextPage());
@@ -1922,9 +1776,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// We give flings precedence over large moves, which is why we short-circuit our
// test for a large move if a fling has been registered. That is, a large
// move to the left and fling to the right will register as a fling to the right.
- final boolean isRtl = isLayoutRtl();
- boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
- boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
+ boolean isDeltaXLeft = mIsRtl ? deltaX > 0 : deltaX < 0;
+ boolean isVelocityXLeft = mIsRtl ? velocityX > 0 : velocityX < 0;
if (((isSignificantMove && !isDeltaXLeft && !isFling) ||
(isFling && !isVelocityXLeft)) && mCurrentPage > 0) {
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
@@ -1983,19 +1836,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mParentDownMotionX = pt[0];
mParentDownMotionY = pt[1];
updateDragViewTranslationDuringDrag();
- boolean handledFling = false;
- if (!DISABLE_FLING_TO_DELETE) {
- // Check the velocity and see if we are flinging-to-delete
- PointF flingToDeleteVector = isFlingingToDelete();
- if (flingToDeleteVector != null) {
- onFlingToDelete(flingToDeleteVector);
- handledFling = true;
- }
- }
- if (!handledFling && isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
- (int) mParentDownMotionY)) {
- onDropToDelete();
- }
} else {
if (!mCancelTap) {
onUnhandledTap(ev);
@@ -2024,17 +1864,14 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return true;
}
- public void onFlingToDelete(View v) {}
- public void onRemoveView(View v, boolean deletePermanently) {}
- public void onRemoveViewAnimationCompleted() {}
- public void onAddView(View v, int index) {}
-
private void resetTouchState() {
releaseVelocityTracker();
endReordering();
mCancelTap = false;
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
+ mEdgeGlowLeft.onRelease();
+ mEdgeGlowRight.onRelease();
}
/**
@@ -2066,7 +1903,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
}
if (hscroll != 0 || vscroll != 0) {
- boolean isForwardScroll = isLayoutRtl() ? (hscroll < 0 || vscroll < 0)
+ boolean isForwardScroll = mIsRtl ? (hscroll < 0 || vscroll < 0)
: (hscroll > 0 || vscroll > 0);
if (isForwardScroll) {
scrollRight();
@@ -2124,22 +1961,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
- protected int getChildWidth(int index) {
- return getPageAt(index).getMeasuredWidth();
- }
-
- int getPageNearestToPoint(float x) {
- int index = 0;
- for (int i = 0; i < getChildCount(); ++i) {
- if (x < getChildAt(i).getRight() - getScrollX()) {
- return index;
- } else {
- index++;
- }
- }
- return Math.min(index, getChildCount() - 1);
- }
-
int getPageNearestToCenterOfScreen() {
int minDistanceFromScreenCenter = Integer.MAX_VALUE;
int minDistanceFromScreenCenterIndex = -1;
@@ -2159,20 +1980,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return minDistanceFromScreenCenterIndex;
}
- protected boolean isInOverScroll() {
- return (mOverScrollX > mMaxScrollX || mOverScrollX < 0);
- }
-
- protected int getPageSnapDuration() {
- if (isInOverScroll()) {
- return OVER_SCROLL_PAGE_SNAP_ANIMATION_DURATION;
- }
- return PAGE_SNAP_ANIMATION_DURATION;
-
- }
-
protected void snapToDestination() {
- snapToPage(getPageNearestToCenterOfScreen(), getPageSnapDuration());
+ snapToPage(getPageNearestToCenterOfScreen(), PAGE_SNAP_ANIMATION_DURATION);
}
private static class ScrollInterpolator implements Interpolator {
@@ -2189,7 +1998,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// the screen has to travel, however, we don't want this duration to be effected in a
// purely linear fashion. Instead, we use this method to moderate the effect that the distance
// of travel has on the overall snap duration.
- float distanceInfluenceForSnapDuration(float f) {
+ private float distanceInfluenceForSnapDuration(float f) {
f -= 0.5f; // center the values about 0.
f *= 0.3f * Math.PI / 2.0f;
return (float) Math.sin(f);
@@ -2200,13 +2009,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
int halfScreenSize = getViewportWidth() / 2;
final int newX = getScrollForPage(whichPage);
- int delta = newX - mUnboundedScrollX;
+ int delta = newX - getScrollX();
int duration = 0;
- if (Math.abs(velocity) < mMinFlingVelocity || isInOverScroll()) {
+ if (Math.abs(velocity) < mMinFlingVelocity) {
// If the velocity is low enough, then treat this more as an automatic page advance
// as opposed to an apparent physical response to flinging
- snapToPage(whichPage, getPageSnapDuration());
+ snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
return;
}
@@ -2229,12 +2038,12 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
snapToPage(whichPage, delta, duration);
}
- protected void snapToPage(int whichPage) {
- snapToPage(whichPage, getPageSnapDuration());
+ public void snapToPage(int whichPage) {
+ snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
}
protected void snapToPageImmediately(int whichPage) {
- snapToPage(whichPage, getPageSnapDuration(), true, null);
+ snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true, null);
}
protected void snapToPage(int whichPage, int duration) {
@@ -2250,8 +2059,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
whichPage = validateNewPage(whichPage);
int newX = getScrollForPage(whichPage);
- final int sX = mUnboundedScrollX;
- final int delta = newX - sX;
+ final int delta = newX - getScrollX();
snapToPage(whichPage, delta, duration, immediate, interpolator);
}
@@ -2270,8 +2078,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
focusedChild.clearFocus();
}
- sendScrollAccessibilityEvent();
-
pageBeginMoving();
awakenScrollBars(duration);
if (immediate) {
@@ -2290,7 +2096,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mScroller.setInterpolator(mDefaultInterpolator);
}
- mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, duration);
+ mScroller.startScroll(getScrollX(), 0, delta, 0, duration);
updatePageIndicator();
@@ -2299,9 +2105,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
computeScroll();
}
- // Defer loading associated pages until the scroll settles
- mDeferLoadAssociatedPagesUntilScrollCompletes = true;
-
mForceScreenScrolled = true;
invalidate();
}
@@ -2328,27 +2131,12 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return result;
}
- /**
- * @return True is long presses are still allowed for the current touch
- */
- public boolean allowLongPress() {
- return mAllowLongPress;
- }
-
@Override
public boolean performLongClick() {
mCancelTap = true;
return super.performLongClick();
}
- /**
- * Set true to allow long-press events to be triggered, usually checked by
- * {@link Launcher} to accept or block dpad-initiated long-presses.
- */
- public void setAllowLongPress(boolean allowLongPress) {
- mAllowLongPress = allowLongPress;
- }
-
public static class SavedState extends BaseSavedState {
int currentPage = -1;
@@ -2356,7 +2144,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
super(superState);
}
- private SavedState(Parcel in) {
+ @Thunk SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@@ -2379,113 +2167,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
};
}
- protected void loadAssociatedPages(int page) {
- loadAssociatedPages(page, false);
- }
- protected void loadAssociatedPages(int page, boolean immediateAndOnly) {
- if (mContentIsRefreshable) {
- final int count = getChildCount();
- if (page < count) {
- int lowerPageBound = getAssociatedLowerPageBound(page);
- int upperPageBound = getAssociatedUpperPageBound(page);
- if (DEBUG) Log.d(TAG, "loadAssociatedPages: " + lowerPageBound + "/"
- + upperPageBound);
- // First, clear any pages that should no longer be loaded
- for (int i = 0; i < count; ++i) {
- Page layout = (Page) getPageAt(i);
- if ((i < lowerPageBound) || (i > upperPageBound)) {
- if (layout.getPageChildCount() > 0) {
- layout.removeAllViewsOnPage();
- }
- mDirtyPageContent.set(i, true);
- }
- }
- // Next, load any new pages
- for (int i = 0; i < count; ++i) {
- if ((i != page) && immediateAndOnly) {
- continue;
- }
- if (lowerPageBound <= i && i <= upperPageBound) {
- if (mDirtyPageContent.get(i)) {
- syncPageItems(i, (i == page) && immediateAndOnly);
- mDirtyPageContent.set(i, false);
- }
- }
- }
- }
- }
- }
-
- protected int getAssociatedLowerPageBound(int page) {
- return Math.max(0, page - 1);
- }
- protected int getAssociatedUpperPageBound(int page) {
- final int count = getChildCount();
- return Math.min(page + 1, count - 1);
- }
-
- /**
- * This method is called ONLY to synchronize the number of pages that the paged view has.
- * To actually fill the pages with information, implement syncPageItems() below. It is
- * guaranteed that syncPageItems() will be called for a particular page before it is shown,
- * and therefore, individual page items do not need to be updated in this method.
- */
- public abstract void syncPages();
-
- /**
- * This method is called to synchronize the items that are on a particular page. If views on
- * the page can be reused, then they should be updated within this method.
- */
- public abstract void syncPageItems(int page, boolean immediate);
-
- protected void invalidatePageData() {
- invalidatePageData(-1, false);
- }
- protected void invalidatePageData(int currentPage) {
- invalidatePageData(currentPage, false);
- }
- protected void invalidatePageData(int currentPage, boolean immediateAndOnly) {
- if (!mIsDataReady) {
- return;
- }
-
- if (mContentIsRefreshable) {
- // Force all scrolling-related behavior to end
- forceFinishScroller();
-
- // Update all the pages
- syncPages();
-
- // We must force a measure after we've loaded the pages to update the content width and
- // to determine the full scroll width
- measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
-
- // Set a new page as the current page if necessary
- if (currentPage > -1) {
- setCurrentPage(Math.min(getPageCount() - 1, currentPage));
- }
-
- // Mark each of the pages as dirty
- final int count = getChildCount();
- mDirtyPageContent.clear();
- for (int i = 0; i < count; ++i) {
- mDirtyPageContent.add(true);
- }
-
- // Load any pages that are necessary for the current window of views
- loadAssociatedPages(mCurrentPage, immediateAndOnly);
- requestLayout();
- }
- if (isPageMoving()) {
- // If the page is moving, then snap it to the final position to ensure we don't get
- // stuck between pages
- snapToDestination();
- }
- }
-
// Animate the drag view back to the original position
- void animateDragViewToOriginalPosition() {
+ private void animateDragViewToOriginalPosition() {
if (mDragView != null) {
AnimatorSet anim = new AnimatorSet();
anim.setDuration(REORDERING_DROP_REPOSITION_DURATION);
@@ -2504,7 +2187,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
- protected void onStartReordering() {
+ public void onStartReordering() {
// Set the touch state to reordering (allows snapping to pages, dragging a child, etc.)
mTouchState = TOUCH_STATE_REORDERING;
mIsReordering = true;
@@ -2514,7 +2197,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
invalidate();
}
- private void onPostReorderingAnimationCompleted() {
+ @Thunk void onPostReorderingAnimationCompleted() {
// Trigger the callback when reordering has settled
--mPostReorderingPreZoomInRemainingAnimationCount;
if (mPostReorderingPreZoomInRunnable != null &&
@@ -2524,7 +2207,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
- protected void onEndReordering() {
+ public void onEndReordering() {
mIsReordering = false;
}
@@ -2574,281 +2257,26 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
onEndReordering();
}
};
- if (!mDeferringForDelete) {
- mPostReorderingPreZoomInRunnable = new Runnable() {
- public void run() {
- onCompleteRunnable.run();
- enableFreeScroll();
- };
- };
-
- mPostReorderingPreZoomInRemainingAnimationCount =
- NUM_ANIMATIONS_RUNNING_BEFORE_ZOOM_OUT;
- // Snap to the current page
- snapToPage(indexOfChild(mDragView), 0);
- // Animate the drag view back to the front position
- animateDragViewToOriginalPosition();
- } else {
- // Handled in post-delete-animation-callbacks
- }
- }
-
- /*
- * Flinging to delete - IN PROGRESS
- */
- private PointF isFlingingToDelete() {
- ViewConfiguration config = ViewConfiguration.get(getContext());
- mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity());
-
- if (mVelocityTracker.getYVelocity() < mFlingToDeleteThresholdVelocity) {
- // Do a quick dot product test to ensure that we are flinging upwards
- PointF vel = new PointF(mVelocityTracker.getXVelocity(),
- mVelocityTracker.getYVelocity());
- PointF upVec = new PointF(0f, -1f);
- float theta = (float) Math.acos(((vel.x * upVec.x) + (vel.y * upVec.y)) /
- (vel.length() * upVec.length()));
- if (theta <= Math.toRadians(FLING_TO_DELETE_MAX_FLING_DEGREES)) {
- return vel;
- }
- }
- return null;
- }
- /**
- * Creates an animation from the current drag view along its current velocity vector.
- * For this animation, the alpha runs for a fixed duration and we update the position
- * progressively.
- */
- private static class FlingAlongVectorAnimatorUpdateListener implements AnimatorUpdateListener {
- private View mDragView;
- private PointF mVelocity;
- private Rect mFrom;
- private long mPrevTime;
- private float mFriction;
-
- private final TimeInterpolator mAlphaInterpolator = new DecelerateInterpolator(0.75f);
-
- public FlingAlongVectorAnimatorUpdateListener(View dragView, PointF vel, Rect from,
- long startTime, float friction) {
- mDragView = dragView;
- mVelocity = vel;
- mFrom = from;
- mPrevTime = startTime;
- mFriction = 1f - (mDragView.getResources().getDisplayMetrics().density * friction);
- }
-
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float t = ((Float) animation.getAnimatedValue()).floatValue();
- long curTime = AnimationUtils.currentAnimationTimeMillis();
-
- mFrom.left += (mVelocity.x * (curTime - mPrevTime) / 1000f);
- mFrom.top += (mVelocity.y * (curTime - mPrevTime) / 1000f);
-
- mDragView.setTranslationX(mFrom.left);
- mDragView.setTranslationY(mFrom.top);
- mDragView.setAlpha(1f - mAlphaInterpolator.getInterpolation(t));
-
- mVelocity.x *= mFriction;
- mVelocity.y *= mFriction;
- mPrevTime = curTime;
- }
- };
-
- private static final int ANIM_TAG_KEY = 100;
-
- private Runnable createPostDeleteAnimationRunnable(final View dragView) {
- return new Runnable() {
- @Override
+ mPostReorderingPreZoomInRunnable = new Runnable() {
public void run() {
- int dragViewIndex = indexOfChild(dragView);
-
- // For each of the pages around the drag view, animate them from the previous
- // position to the new position in the layout (as a result of the drag view moving
- // in the layout)
- // NOTE: We can make an assumption here because we have side-bound pages that we
- // will always have pages to animate in from the left
- getFreeScrollPageRange(mTempVisiblePagesRange);
- boolean isLastWidgetPage = (mTempVisiblePagesRange[0] == mTempVisiblePagesRange[1]);
- boolean slideFromLeft = (isLastWidgetPage ||
- dragViewIndex > mTempVisiblePagesRange[0]);
-
- // Setup the scroll to the correct page before we swap the views
- if (slideFromLeft) {
- snapToPageImmediately(dragViewIndex - 1);
- }
-
- int firstIndex = (isLastWidgetPage ? 0 : mTempVisiblePagesRange[0]);
- int lastIndex = Math.min(mTempVisiblePagesRange[1], getPageCount() - 1);
- int lowerIndex = (slideFromLeft ? firstIndex : dragViewIndex + 1 );
- int upperIndex = (slideFromLeft ? dragViewIndex - 1 : lastIndex);
- ArrayList<Animator> animations = new ArrayList<Animator>();
- for (int i = lowerIndex; i <= upperIndex; ++i) {
- View v = getChildAt(i);
- // dragViewIndex < pageUnderPointIndex, so after we remove the
- // drag view all subsequent views to pageUnderPointIndex will
- // shift down.
- int oldX = 0;
- int newX = 0;
- if (slideFromLeft) {
- if (i == 0) {
- // Simulate the page being offscreen with the page spacing
- oldX = getViewportOffsetX() + getChildOffset(i) - getChildWidth(i)
- - mPageSpacing;
- } else {
- oldX = getViewportOffsetX() + getChildOffset(i - 1);
- }
- newX = getViewportOffsetX() + getChildOffset(i);
- } else {
- oldX = getChildOffset(i) - getChildOffset(i - 1);
- newX = 0;
- }
-
- // Animate the view translation from its old position to its new
- // position
- AnimatorSet anim = (AnimatorSet) v.getTag();
- if (anim != null) {
- anim.cancel();
- }
-
- // Note: Hacky, but we want to skip any optimizations to not draw completely
- // hidden views
- v.setAlpha(Math.max(v.getAlpha(), 0.01f));
- v.setTranslationX(oldX - newX);
- anim = new AnimatorSet();
- anim.playTogether(
- ObjectAnimator.ofFloat(v, "translationX", 0f),
- ObjectAnimator.ofFloat(v, "alpha", 1f));
- animations.add(anim);
- v.setTag(ANIM_TAG_KEY, anim);
- }
-
- AnimatorSet slideAnimations = new AnimatorSet();
- slideAnimations.playTogether(animations);
- slideAnimations.setDuration(DELETE_SLIDE_IN_SIDE_PAGE_DURATION);
- slideAnimations.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mDeferringForDelete = false;
- onEndReordering();
- onRemoveViewAnimationCompleted();
- }
- });
- slideAnimations.start();
-
- removeView(dragView);
- onRemoveView(dragView, true);
- }
- };
- }
-
- public void onFlingToDelete(PointF vel) {
- final long startTime = AnimationUtils.currentAnimationTimeMillis();
-
- // NOTE: Because it takes time for the first frame of animation to actually be
- // called and we expect the animation to be a continuation of the fling, we have
- // to account for the time that has elapsed since the fling finished. And since
- // we don't have a startDelay, we will always get call to update when we call
- // start() (which we want to ignore).
- final TimeInterpolator tInterpolator = new TimeInterpolator() {
- private int mCount = -1;
- private long mStartTime;
- private float mOffset;
- /* Anonymous inner class ctor */ {
- mStartTime = startTime;
- }
-
- @Override
- public float getInterpolation(float t) {
- if (mCount < 0) {
- mCount++;
- } else if (mCount == 0) {
- mOffset = Math.min(0.5f, (float) (AnimationUtils.currentAnimationTimeMillis() -
- mStartTime) / FLING_TO_DELETE_FADE_OUT_DURATION);
- mCount++;
- }
- return Math.min(1f, mOffset + t);
- }
+ onCompleteRunnable.run();
+ enableFreeScroll();
+ };
};
- final Rect from = new Rect();
- final View dragView = mDragView;
- from.left = (int) dragView.getTranslationX();
- from.top = (int) dragView.getTranslationY();
- AnimatorUpdateListener updateCb = new FlingAlongVectorAnimatorUpdateListener(dragView, vel,
- from, startTime, FLING_TO_DELETE_FRICTION);
-
- final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
-
- // Create and start the animation
- ValueAnimator mDropAnim = new ValueAnimator();
- mDropAnim.setInterpolator(tInterpolator);
- mDropAnim.setDuration(FLING_TO_DELETE_FADE_OUT_DURATION);
- mDropAnim.setFloatValues(0f, 1f);
- mDropAnim.addUpdateListener(updateCb);
- mDropAnim.addListener(new AnimatorListenerAdapter() {
- public void onAnimationEnd(Animator animation) {
- onAnimationEndRunnable.run();
- }
- });
- mDropAnim.start();
- mDeferringForDelete = true;
- }
-
- /* Drag to delete */
- private boolean isHoveringOverDeleteDropTarget(int x, int y) {
- if (mDeleteDropTarget != null) {
- mAltTmpRect.set(0, 0, 0, 0);
- View parent = (View) mDeleteDropTarget.getParent();
- if (parent != null) {
- parent.getGlobalVisibleRect(mAltTmpRect);
- }
- mDeleteDropTarget.getGlobalVisibleRect(mTmpRect);
- mTmpRect.offset(-mAltTmpRect.left, -mAltTmpRect.top);
- return mTmpRect.contains(x, y);
- }
- return false;
+ mPostReorderingPreZoomInRemainingAnimationCount =
+ NUM_ANIMATIONS_RUNNING_BEFORE_ZOOM_OUT;
+ // Snap to the current page
+ snapToPage(indexOfChild(mDragView), 0);
+ // Animate the drag view back to the front position
+ animateDragViewToOriginalPosition();
}
- protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {}
-
- private void onDropToDelete() {
- final View dragView = mDragView;
-
- final float toScale = 0f;
- final float toAlpha = 0f;
-
- // Create and start the complex animation
- ArrayList<Animator> animations = new ArrayList<Animator>();
- AnimatorSet motionAnim = new AnimatorSet();
- motionAnim.setInterpolator(new DecelerateInterpolator(2));
- motionAnim.playTogether(
- ObjectAnimator.ofFloat(dragView, "scaleX", toScale),
- ObjectAnimator.ofFloat(dragView, "scaleY", toScale));
- animations.add(motionAnim);
-
- AnimatorSet alphaAnim = new AnimatorSet();
- alphaAnim.setInterpolator(new LinearInterpolator());
- alphaAnim.playTogether(
- ObjectAnimator.ofFloat(dragView, "alpha", toAlpha));
- animations.add(alphaAnim);
-
- final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
-
- AnimatorSet anim = new AnimatorSet();
- anim.playTogether(animations);
- anim.setDuration(DRAG_TO_DELETE_FADE_OUT_DURATION);
- anim.addListener(new AnimatorListenerAdapter() {
- public void onAnimationEnd(Animator animation) {
- onAnimationEndRunnable.run();
- }
- });
- anim.start();
-
- mDeferringForDelete = true;
- }
+ private static final int ANIM_TAG_KEY = 100;
/* Accessibility */
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
@@ -2859,6 +2287,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (getCurrentPage() > 0) {
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
}
+ info.setClassName(getClass().getName());
+
+ // Accessibility-wise, PagedView doesn't support long click, so disabling it.
+ // Besides disabling the accessibility long-click, this also prevents this view from getting
+ // accessibility focus.
+ info.setLongClickable(false);
+ if (Utilities.isLmpOrAbove()) {
+ info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
+ }
}
@Override
@@ -2872,7 +2309,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
- event.setScrollable(true);
+ event.setScrollable(getPageCount() > 1);
}
@Override