使用较短的拖动使ViewPager捕捉

时间:2013-06-26 11:19:35

标签: android android-viewpager gesture

有没有办法让支持包ViewPager以较短的阻力捕捉到下一页?默认行为似乎是,即使我拖动了近75%的页面,当我放手时页面仍会快速回到上一页。我想缩短捕捉阈值并使ViewPager成为下一页的对象。

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

4 个答案:

答案 0 :(得分:22)

只要您想增加目标区域,您就可以临时执行此操作,而无需过多担心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;
    }
}

答案 1 :(得分: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

答案 2 :(得分:0)

以下是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
        }
    }

 }

答案 3 :(得分:0)

我使用反射来做到这一点。通过将专用字段mMinimumVelocity设置为-1,可以使ViewPager将所有滚动作为滚动滚动-需要更短的拖动才能切换到下一页。就像魅力一样!

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

我知道私有字段的源代码是here

此外,如果您想使阈值略大于下移滚动的默认25dp,则可以将mFlingDistance字段设置为更高的值,例如45dp。但是请记住,它也会影响实际弹跳所需的拖动距离。

Field mFlingDistance;
mFlingDistance= ViewPager.class.getDeclaredField("mFlingDistance");
mFlingDistance.setAccessible(true);
mFlingDistance.set(mPager, (int) (45 * context.getResources().getDisplayMetrics().density));