ViewPager拦截了所有的x轴onTouch事件。如何禁用?

34

范围

有一个包含两个片段的viewpager。其中一个片段具有侦听X轴onTouch变化的布局。

问题

当触摸并沿着X轴滑动时,布局几乎无法获取所有Action.Move事件。似乎viewpager具有返回true的onInterceptTouchEvent。

问题

是否真的可以覆盖viewpager的行为以使其与我的布局共同工作?因此,完美的情况是布局拦截其上的所有onTouch事件,而viewpager则管理其余的onTouch事件。谢谢!


我在一个由ViewPager控制的Fragment视图中使用了列表(list) ... 我也遇到了相同的问题...如果开始滑动,它会在x方向上轻微移动...我也尝试过@neutrino,但问题仍然存在...有什么建议/想法吗? - CoDe
另外,我在Fragment中使用了Listview...所以我必须为list view也要求requestDisallowInterceptTouchEvent true...但现在很麻烦...因为它正在拦截列表事件的点击事件...有什么建议/更新吗? - CoDe
这里有一些有趣的东西:https://dev59.com/AGsz5IYBdhLWcg3wj4ra#7814054 - CoDe
4个回答

43

你是正确的,我相信每个滚动容器都会拦截触摸事件,但你可以防止它。你可以在你的布局上放置一个触摸监听器:

public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_MOVE: 
        pager.requestDisallowInterceptTouchEvent(true);
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
        pager.requestDisallowInterceptTouchEvent(false);
        break;
    }
}

谢谢!我应该更耐心、更仔细地阅读 Android 文档。 - Oleksii Malovanyi
2
这只能在onTouch中运行吗?我尝试在onScale中使用它,但仍然会拦截我的触摸。 - devanshu_kaushik
5
两个注意点:
  1. 你不必保留对页面的引用 - 调用 getParent().request... 就足够了,父级将传播请求。这使得在自定义视图中更加灵活可用。
  2. 起初我认为仅在初始化时为视图调用一次 request... 就足够了。但实际上必须为每个触摸事件都调用它。这就是为什么你必须在 onTouch() 中这样做。 @dev_android
- Michał Klimczak
1
这样就可以防止用户在我的图片上水平滑动时切换选项卡。太棒了! - Someone Somewhere
如果您在滑动监听onTouch事件的布局上调用pager adapter的notifyDataSetChanged来更新ViewPager的内容,则它将不再起作用!然后ViewPager会翻转。有人知道解决方法吗? - DominicM
非常好的答案,解决了我的ViewPager拦截向下滚动事件的问题。 - reixa

19

类似的情况(但不使用ViewPager),将此代码添加到需要触摸事件的视图中,对我起到了作用。如果适用于您的用例,请添加对除 ACTION_MOVE 之外的 MotionEvent 的检查。

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_MOVE) {
        this.getParent().requestDisallowInterceptTouchEvent(true);
        return true;
    } else {
        return super.onTouchEvent(event);
    }
}

这是正确的解决方案,但我想指出,如果您不返回true,则此事件仍将由ViewPager(或任何中间ViewGroups)处理。如果您返回false,则该事件未处理,并将向上传播到ViewPager。 - nacitar sevaht

1
中性子是正确的!
getParent().requestDisallowInterceptTouchEvent(true);

一旦ViewPager访问了TouchEvent拦截,其中的子视图就可以获得事件。 点击此处查看图片描述 我在ViewPager中使用FrameLayout来实现DrawerLayout效果(我需要它不匹配屏幕高度,因此无法使用drawerlayout或navigation drawer)。 这真的很有帮助!

-1

我曾经遇到过类似的问题。

我的情况是在ViewPager上设置了一个OnTouchListener,但当接收触摸事件的子元素有onClick时,它无法接收到触摸事件。

我所做的是扩展ViewPager类,并在方法onInterceptTouchEvent(boolean)中调用我的点击监听器,这样就可以正常工作了。只要小心不要拦截错误的事件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接