使用多个视图/布局时在 Android 中处理触摸事件

Posted

技术标签:

【中文标题】使用多个视图/布局时在 Android 中处理触摸事件【英文标题】:handling touch events in Android when using multiple views/layouts 【发布时间】:2012-08-13 13:11:15 【问题描述】:

我对 android 编程非常陌生,并试图通过嵌套视图来理解触摸事件。首先,这是对我的应用的描述:

我有一个通过 GUI 编辑器添加的相对布局。一切都是默认的。我还创建了一个名为 ClipGrid 的类,它扩展了 ScrollView。嵌套在其中,我制作了一个 Horizo​​ntalScrollView。在其中,我制作了一个 TableLayout 和它的行。这些行包含按钮。

最终结果是一个按钮网格。它一次显示 4x4,但可以滚动任一方向以显示其他按钮。

我从我的主要活动中将其调用到屏幕上,如下所示: ClipGrid clip_grid = new ClipGrid(this); setContentView(clip_grid);

我这样做只是为了测试目的,我想我以后想在我的 relativelayout 中添加其他视图时必须更改它。但我认为它可能会对触摸事件产生影响。

最后,我想检测网格何时移动,并在用户抬起手指时将新可见的 4x4 按钮网格捕捉到我的布局边缘。我只是不确定如何实施这一点,任何帮助将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

触摸事件的处理方式是一种级联效果,从顶部视图开始向下到较低的嵌套视图。基本上,Android 会将事件传递给每个视图,直到返回 true

实现onTouchEvent 事件View 的一般方法是:

@Override
public boolean onTouchEvent(MotionEvent event) 
  boolean actionHandled = false;
  final int action = event.getAction();

  switch(action & MotionEventCompat.ACTION_MASK) 
    case MotionEvent.ACTION_DOWN:
      // user first touches view with pointer
      break;
    case MotionEvent.ACTION_MOVE:
      // user is still touching view and moving pointer around
      break;
    case MotionEvent.ACTION_UP:
      // user lifts pointer
      break;
  

  // if the action was not handled by this touch, send it to other views
  if (!actionHandled) 
     actionHandled |= super.onTouch(v, MotionEvent.event);

  return actionHandled;

【讨论】:

感谢您的回复。所以,假设我希望我的表格布局能够处理触摸事件。由于它嵌套在水平滚动视图和滚动视图中,我是从那些父视图中返回 false(从表布局中返回 true),还是不实现该事件?作为旁注,有没有更好的方法来实现我想要做的事情? 如果 View 不处理触摸事件,则不要实现它。默认情况下,它们返回 false。从它的声音来看,您可能想查看ViewPager。除此之外,您可能还想检测ScrollView 中的滑动事件。它给出并知道它的孩子的尺寸。如果它控制动作而不是控制孩子也会更好。使用ScrollViews,您还可以使用onInterceptTouchEvent(),它基本上从顶部视图中窃取触摸事件来处理它,然后再将事件提供给孩子。 谢谢,这让我朝着正确的方向前进,现在我可以正常工作了。事实证明,我必须从滚动视图或其嵌套的水平滚动视图中实现一个 onTouchListener,否则它只会检测到一个方向的滚动。此外,从其中任何一个返回 true 实际上都会阻止表格布局滚动。

以上是关于使用多个视图/布局时在 Android 中处理触摸事件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 android 视图上禁用所有用户输入(点击、触摸)

触摸编辑时,Android 键盘视图位于 EditText 前面

跨多个子视图处理触摸事件

使用自动布局进行编辑时在表格视图中调整子视图的大小

Android:Slidingdrawer.lock() 阻止其余布局的触摸输入

使用 Swift 3 触摸时在 Webview 中获取 pdf 的实际坐标