Vertical ViewPager and Android Pie Inconsistent Behavior with Swipe Gesture

前端 未结 3 1938
清歌不尽
清歌不尽 2020-12-28 09:25

My problem is closely related to two other questions that haven\'t been answered yet.

ViewPager not responding to touch in layout area created dynamically in Fragmen

3条回答
  •  臣服心动
    2020-12-28 09:38

    The problem seems to be in the way #swapXY exchanges the x and y values. I believe that the VelocityTracker used in ViewPager uses #getAxisValue and not #getX/#getY, and the result is not swapped. But there doesn't seem to be a way to set the axis values nor to subclass MotionEvent so I didn't find a way to stick with the simple #swapXY solution. I forked ViewPager and use VelocityTracker.getYVelocity when I detect the unswapped condition.

    diff --git project/src/main/java/org/gc/project/util/ShopVerticalViewPager.java project/src/main/java/org/gc/project/util/ShopVerticalViewPager.java
    index e5560a0..f23f9f7 100644
    --- project/src/main/java/org/gc/project/util/MyVerticalViewPager.java
    +++ project/src/main/java/org/gc/project/util/MyVerticalViewPager.java
    @@ -179,4 +179,8 @@ public class ShopVerticalViewPager extends ViewPager {
    return super.onTouchEvent( swapXY( ev ) );
    }
    
    + public boolean isVerticalMode() {
    + return true;
    + }
    +
    }
    \ No newline at end of file
    diff --git project/src/main/java/gcandroid/support/v4/view/ViewPager.java project/src/main/java/gcandroid/support/v4/view/ViewPager.java
    index 20e1448..4ae2d3c 100644
    --- project/src/main/java/gcandroid/support/v4/view/ViewPager.java
    +++ project/src/main/java/gcandroid/support/v4/view/ViewPager.java
    @@ -205,6 +205,7 @@ public class ViewPager extends ViewGroup {
    private int mMaximumVelocity;
    private int mFlingDistance;
    private int mCloseEnough;
    + private boolean mInvertedVelocityTrackerInVerticalMode = false;
    
    // If the pager is at least this close to its final position, complete the scroll
    // on touch down and let the user interact with the content inside instead of
    @@ -391,6 +392,21 @@ public class ViewPager extends ViewGroup {
    ViewCompat.setImportantForAccessibility(this,
    ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
    }
    +
    + // tell if the velocity tracker is inverted in vertical mode (most probably uses MotionEvent.getAxisValue instead of MotionEvent.getX but
    + // I can't change these values nor inherit from MotionEvent)
    + VelocityTracker vt = VelocityTracker.obtain();
    + long time = SystemClock.uptimeMillis();
    + MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0);
    + vt.addMovement(ev);
    + ev.recycle();
    + ev = MotionEvent.obtain(time, time + 10, MotionEvent.ACTION_MOVE, 10, 0, 0);
    + ev.setLocation( 0, 10 );
    + vt.addMovement(ev);
    + ev.recycle();
    + vt.computeCurrentVelocity(1000, mMaximumVelocity);
    + mInvertedVelocityTrackerInVerticalMode = vt.getYVelocity() == 0;
    + vt.recycle();
    }
    
    @Override
    @@ -2027,6 +2043,10 @@ public class ViewPager extends ViewGroup {
    return mIsBeingDragged;
    }
    
    + public boolean isVerticalMode() {
    + return false;
    + }
    +
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
    if (mFakeDragging) {
    @@ -2111,8 +2131,9 @@ public class ViewPager extends ViewGroup {
    if (mIsBeingDragged) {
    final VelocityTracker velocityTracker = mVelocityTracker;
    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
    - int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(
    - velocityTracker, mActivePointerId);
    + int initialVelocity = (int) ( isVerticalMode() && mInvertedVelocityTrackerInVerticalMode ? VelocityTrackerCompat.getYVelocity( velocityTracker, mActivePointerId )
    + : VelocityTrackerCompat.getXVelocity( velocityTracker, mActivePointerId ) );
    +
    mPopulatePending = true;
    final int width = getClientWidth();
    final int scrollX = getScrollX();
    

提交回复
热议问题