8

我正在开发一个具有ViewPager菜单的应用程序。每个fragment都有一堆子视图,可以是ListView, ScrollView, LinearLayout, 等等......其中一个fragments有一个设置按钮,它使用一个和一些(按钮)以及作为子级来切换设置面板(LinearLayout包装器) 。此设置面板使用向上或向下滑动动画(关闭时)进行动画处理,当它可见时,我禁用分页:ScrollViewLinearLayoutSeekBarViewPager

@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动作(移动和向上),我可以快速向上、向下、侧向等滑动。ViewPager不会翻页,但ListView像魅力一样滑动。

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

所以我的问题是,我走在正确的道路上吗?无论如何要避免将此侦听器添加到所有面板子视图中(当然,如果我必须这样做,我会以最通用的方式进行)?

谢谢你的时间。

4

2 回答 2

25

禁用分页应该像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);
    }

}

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

于 2014-09-19T14:45:45.823 回答
1

您只需在viewpager 上调用此方法即可禁用 viewpager 中的分页

view_pager。设置用户输入启用(假)

阅读更多

于 2021-05-25T06:03:14.350 回答