18

有什么方法可以使支持包 ViewPager 以更短的拖动方式捕捉到下一页?默认行为似乎是,即使我拖动了将近 75%,当我放手时,页面仍然会快速回到上一页。我想缩短捕捉阈值并让 ViewPager 捕捉到下一页。

请注意,这适用于拖动手势。投掷手势已经需要更短的手势。

4

4 回答 4

24

只要您想增加目标区域,您就可以临时执行此操作,而无需过多担心 ViewPager 的内部结构:

private class MyPageChangeListener implements OnPageChangeListener {
    private float mLastPositionOffset = 0f;
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if(positionOffset < mLastPositionOffset && positionOffset < 0.9) {
            mViewPager.setCurrentItem(position);
        } else if(positionOffset > mLastPositionOffset && positionOffset > 0.1) {
            mViewPager.setCurrentItem(position+1);
        }
        mLastPositionOffset = positionOffset;
    }
}
于 2013-06-26T14:05:33.160 回答
1

看起来这些值是在私有方法中硬编码的,因此没有简单的方法可以覆盖它们。

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/support/v4/view/ViewPager.java#2075

于 2013-06-26T13:33:50.090 回答
1

这是我在Librera Reader中使用的代码

public class MyViewPager extends ViewPager {

  public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        initMyScroller();
    }

    private void initMyScroller() {
        try {
            Class<?> viewpager = ViewPager.class;
            Field scroller = viewpager.getDeclaredField("mScroller");
            scroller.setAccessible(true);
            scroller.set(this, new MyScroller(getContext())); // my liner scroller

            Field mFlingDistance = viewpager.getDeclaredField("mFlingDistance");
            mFlingDistance.setAccessible(true);
            mFlingDistance.set(this, Dips.DP_10);//10 dip short drag

            Field mMinimumVelocity = viewpager.getDeclaredField("mMinimumVelocity");
            mMinimumVelocity.setAccessible(true);
            mMinimumVelocity.set(this, 0); //0 velocity

        } catch (Exception e) {
            LOG.e(e);
        }

    }

    public class MyScroller extends Scroller {
        public MyScroller(Context context) {
            super(context, new LinearInterpolator()); // my LinearInterpolator
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, 175);//175 duration
        }
    }

 }
于 2018-03-12T13:20:53.617 回答
1

我使用反射做到了这一点。通过将私有字段设置mMinimumVelocity-1,您可以使 ViewPager 将您的所有滚动都作为一个快速滚动 - 这需要更短的拖动才能切换到下一页。奇迹般有效!

Field mMinimumVelocity;
mMinimumVelocity = ViewPager.class.getDeclaredField("mMinimumVelocity");
mMinimumVelocity.setAccessible(true);
mMinimumVelocity.set(mPager, -1);

我知道私有字段的源代码在这里

此外,如果您想让阈值比默认滚动的 25dp 大一点,您可以将该mFlingDistance字段设置为更高的值,例如 45dp。但请记住,它也会影响实际滑动滚动所需的拖动距离。

Field mFlingDistance;
mFlingDistance= ViewPager.class.getDeclaredField("mFlingDistance");
mFlingDistance.setAccessible(true);
mFlingDistance.set(mPager, (int) (45 * context.getResources().getDisplayMetrics().density));
于 2018-12-31T09:46:05.957 回答