我正在开发一个带有ViewPager作为菜单的应用程序。每个fragment都有一堆 subview ,可以是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;
}

但这带来了一个问题,每次面板打开时,所有 subview 都不会收到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和UP),并且我可以快速向上,向下,侧向滑动等。 ViewPager像魅力一样滑动。

但是问题仍然存在,我必须将此ListView添加到所有 subview requestDisallowInterceptTouchEvent(true),这不是优雅的代码。
所以我的问题是,我走在正确的道路上?无论如何,要避免将此监听器添加到所有面板 subview 中(当然,如果需要的话,我将以最通用的方式来做)?
谢谢你的时间。

最佳答案

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

}

由于相同的原因,我在其中一个应用程序中使用了相同的名称(名称不同),它肯定可以正常工作。

关于android - 禁用ViewPager分页的最佳方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25935890/

10-12 06:13