禁用ViewPager分页的最佳方法

时间:2014-09-19 14:07:03

标签: android android-viewpager scroll-paging

我正在开发一个以ViewPager作为菜单的应用。每个fragment都有一堆子视图,可以是ListViewScrollViewLinearLayout等等。 其中一个fragments有一个设置按钮,可以使用LinearLayout和一些ScrollView(按钮)切换设置面板(LinearLayout包装) SeekBar作为孩子。这个设置面板带有向上或向下滑动动画(当被解除时),当它可见时,我禁用了ViewPager分页:

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (!pagingEnabled && event.getAction() == MotionEvent.ACTION_MOVE) {
        return true;
    }
    return super.onTouchEvent(event);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (!pagingEnabled && event.getAction() == MotionEvent.ACTION_MOVE) {
        return true;
    }
    return super.onInterceptTouchEvent(event);
}

public boolean isPagingEnabled() {
    return pagingEnabled;
}

public void setPagingEnabled(boolean pagingEnabled) {
    this.pagingEnabled = pagingEnabled;
}

但是这出现了问题,每次面板启动时,所有子视图都不会收到OnTouchEvent,这就是为什么我添加了GestureDetector.SimpleOnGestureListener

protected class YScrollDetector extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        Log.i(C.TAG, "distanceX " + distanceX + " distanceY " + distanceY);
        return Math.abs(distanceY) < Math.abs(distanceX);
    }
}

并将我的ViewPager onInterceptTouchEvent更改为:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (!pagingEnabled && event.getAction() == MotionEvent.ACTION_MOVE && (mGestureDetector != null && mGestureDetector.onTouchEvent(event))) {
        return true;
    }
    return super.onInterceptTouchEvent(event);
}

这样做,面板按钮接收他们的onClick,ListView滑动等...但这不是那么完美,因为Math.abs(distanceY) < Math.abs(distanceX)它并不准确。如果我快速上下或对角快速滑动,或者如果我通过轻微滑动触摸按钮,onInterceptTouchEvent将返回true,因为mGestureDetector.onTouchEvent(event)也将返回true

经过一些谷歌搜索,我发现了这个:

viewPager.requestDisallowInterceptTouchEvent(true);

我尝试过这样的事情:

myListView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        viewPager.requestDisallowInterceptTouchEvent(true);
        return false;
    }
});

它的效果非常好,因为ViewPager.onInterceptTouchEvent首先调用MotionEvent.ACTION_DOWN,然后myListView.setOnTouchListener调用它,然后禁用剩余的MotionEvent个动作(MOVE AND UP)和我可以快速向上,向下,向侧面等方向向上滑动。ViewPager不会页面,但ListView滑动就像一个魅力。

但问题仍然存在,我要将此requestDisallowInterceptTouchEvent(true)添加到所有子视图onTouchEvent,并且它不是优雅的代码。

所以我的问题是,我走在正确的道路上?反正是为了避免将这个监听器添加到所有面板子视图中(当然如果我必须以最通用的方式进行)?

谢谢你的时间。

2 个答案:

答案 0 :(得分:22)

禁用分页应该像从falseonInterceptTouchEvent返回onTouchEvent一样简单。您不应该需要额外的手势检测来绕过ViewPager。像这样扩展ViewPager

public class MyViewPager extends ViewPager {
    private boolean pagingEnabled = true;

    public MyViewPager(Context context) {
        super(context);
    }

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

    public void setPagingEnabled(boolean pagingEnabled) {
        this.pagingEnabled = pagingEnabled;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return pagingEnabled && super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return pagingEnabled && super.onTouchEvent(event);
    }

}

我在我的一个应用程序中使用相同的东西(使用不同的名称)出于同样的原因,它肯定有效。

答案 1 :(得分:1)

您可以在 viewpager禁用分页,只需调用 你的viewpager上的这个方法

<块引用>

view_pager.setUserInputEnabled(false)

Read more