禁用ViewPager分页的最佳方法

Gui*_*lhE 8 android android-viewpager scroll-paging

我正在开发一个有ViewPager菜单的应用程序.每个fragment有一堆的可以是孩子的意见ListView,ScrollView,LinearLayout,等...一本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;
}
Run Code Online (Sandbox Code Playgroud)

但是这出现了一个问题,每次面板启动时,所有孩子的观点都不会收到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);
    }
}
Run Code Online (Sandbox Code Playgroud)

并改为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);
}
Run Code Online (Sandbox Code Playgroud)

这工作,面板按钮接收他们的onClick,ListView滑动等...但这不是很完美,因为Math.abs(distanceY) < Math.abs(distanceX)它不是那么准确.如果我快速上下滑动或斜向滑动,或者如果我轻触滑动按钮,onInterceptTouchEvent则会返回,true因为它mGestureDetector.onTouchEvent(event)也会返回true.

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

viewPager.requestDisallowInterceptTouchEvent(true);
Run Code Online (Sandbox Code Playgroud)

我尝试过这样的事情:

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

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

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

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

谢谢你的时间.

Kar*_*uri 24

禁用分页应为返回简单false从两个onInterceptTouchEventonTouchEvent.您不应该需要额外的手势检测来绕过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);
    }

}
Run Code Online (Sandbox Code Playgroud)

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