0

问题

在为滑动手势上的 ListView 项目开发某种“上下文操作”时,我对 Android 将 MotionEvents 分派给 ViewGroup 的孩子的方式有点困惑。

根据文档,所有事情都从ViewGroupd.dispatchTouchEvent(MotionEvent)方法调用开始。然后视图组询问是否应该拦截特定的运动事件,或者我们可以将其分派给我们的孩子。这适用于各种滚动,因此我们可以有效地解决垂直和水平滚动之间的冲突(例如 ViewPager 中的 ListView)。

但是,我无法以这种方式成功处理列表视图中的简单单击事件。运动事件调度跟踪看起来像这样

  1. ListView.dispatchTouchEvent(DOWN)
  2. ListView.onInterceptTouchEvent(DOWN) 返回false
  3. QuickActionView.dispatchTouchEvent(DOWN)
  4. QuickActionView.onTouchEvent(DOWN) returntrue因为 MotionEvent.ACTION_DOWN 表示手势的开始,它可能是水平滚动,在这种情况下我们应该向用户显示快速操作布局。如果我们false从这里返回,MotionEvent.ACTION_DOWN它会阻止其他触摸事件被分派给 ListView 的这个子项。
  5. 由于第 4 步QuickActionView.dispatchTouchEvent(DOWN) 返回true
  6. 由于第 5 步ListView.dispatchTouchEvent(DOWN) 返回true

结果 ListView 记住了触摸目标。所以下一条消息是这样发送的。

  1. ListView.dispatchTouchEvent(UP)
  2. ListView.onInterceptTouchEvent(UP) 返回false
  3. QuickActionView.dispatchTouchEvent(UP)
  4. QuickActionView.onTouchEvent(UP) returnfalse因为我们现在看到手势已经结束,它不是滚动或投掷或其他任何东西。
  5. 由于第 4 步QuickActionView.dispatchTouchEvent(UP) 返回false
  6. 由于第 5 步ListView.dispatchTouchEvent(UP) 返回false

因此,ListView 没有机会处理项目点击,因为在步骤 5 之后使用 UP 操作,运动事件不会定向到 ListView 的onTouchEvent(MotionEvent)方法。

我还尝试在 ListView 中使用 ACTION_UP “拦截”触摸事件,但注意到根据 Android 文档,拦截后只有进一步的运动事件将被定向到 ViewGroup 的onTouchEvent(MotionEvent)方法,而当前的不会。

问题

如何同时支持 ListView 的本机项目单击处理和将 MotionEvents 分派到 ListItem 视图的能力(它是水平滚动的并具有图像按钮)?

最好听取在此类问题解决方面经验丰富的人的意见,或者对其设计如何与特定的冲突解决有更深入的了解

4

1 回答 1

0

目前我有两个解决这个问题的方法

  1. 将 QuickActionView(实际上是 ListView 项)分为两部分:
 ____________________
| clickable      |  |   
|________________|__|
                   ^
                   |
                  scrollable

这样我就无法滚动 ListView 项目,以防初始 ACTION_DOWN 运动事件从可点击区域开始,但列表视图本机处理项目点击。而且我无法单击可滚动区域内的列表项,而如果我的手势从可滚动区域开始,我可以滚动以显示快速操作。

  1. 第二个解决方案相当hacky,但避免了第一个的限制在ListView里面我可以通过MotionEvent.obtain(MotionEvent)方法记住所有的触摸事件。然后我等待 ACTION_UP MotionEvent 并询问 listItem 视图是否已处理手势。如果列表项告诉手势尚未处理,我将调用私有方法ListView.cancelTouchTarget()并将所有保存的 MotionEvents 通过super.dispatchTouchEvent(MotionEvent)
于 2013-07-10T10:59:07.397 回答