使用多个视图/布局时在 Android 中处理触摸事件
Posted
技术标签:
【中文标题】使用多个视图/布局时在 Android 中处理触摸事件【英文标题】:handling touch events in Android when using multiple views/layouts 【发布时间】:2012-08-13 13:11:15 【问题描述】:我对 android 编程非常陌生,并试图通过嵌套视图来理解触摸事件。首先,这是对我的应用的描述:
我有一个通过 GUI 编辑器添加的相对布局。一切都是默认的。我还创建了一个名为 ClipGrid 的类,它扩展了 ScrollView。嵌套在其中,我制作了一个 HorizontalScrollView。在其中,我制作了一个 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 前面