我正在开发一个带有ViewPager
作为菜单的应用程序。每个fragment
都有一堆 subview ,可以是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;
}
但这带来了一个问题,每次面板打开时,所有 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 中(当然,如果需要的话,我将以最通用的方式来做)?
谢谢你的时间。
最佳答案
禁用分页应该就像从false
和onInterceptTouchEvent
返回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/