我正在开发一个以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;
}
但是这出现了问题,每次面板启动时,所有子视图都不会收到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
,并且它不是优雅的代码。
所以我的问题是,我走在正确的道路上?反正是为了避免将这个监听器添加到所有面板子视图中(当然如果我必须以最通用的方式进行)?
谢谢你的时间。
答案 0 :(得分:22)
禁用分页应该像从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);
}
}
我在我的一个应用程序中使用相同的东西(使用不同的名称)出于同样的原因,它肯定有效。
答案 1 :(得分:1)