【问题标题】:How to obtain the underlying view from a MotionEvent?如何从 MotionEvent 中获取底层视图?
【发布时间】:2011-05-23 03:28:55
【问题描述】:

我的 GestureListener 类在 onSingleTap() 或 onFling() 等方法中接收到 MotionEvent。有没有办法从这个事件中确定底层视图?

背景:我有一个包含许多子视图的 LinearLayout。此 LinearLayout 上有一个触摸侦听器,它调用手势检测器。因此,当用户在任何子视图上做手势时,LinearLayout 的手势检测器会收到一个 MotionEvent。但问题是,因为有很多孩子,我需要确切地知道用户点击了哪个孩子。但是我找不到将坐标转换为视图的方法。有没有办法做到这一点?

一个丑陋的解决方案:动态添加孩子。所以我可以将所有的孩子保存在一个列表中,然后当一个 MotionEvent 来临时,我可以遍历列表并查看该点是否在一个孩子内部。但我不喜欢这个主意。有没有更好的办法?

【问题讨论】:

    标签: android


    【解决方案1】:

    您确定要在布局上使用触摸侦听器吗?为什么不让每个视图都有一个触摸监听器?

    假设您有一堆需要弹跳才能切换的开关。开关控制怪物。你可以让每个开关(你的视图)都有一个触摸监听器,将开关传递给怪物。现在怪物可以以不同的方式处理每个视图。

    类似这样的:

    brightnessSwitch.setOnTouchListener( new View.OnTouchListener() {
      boolean onTouch(View v, MotionEvent event) {
        monster.toggleBrightness();
        return true;
      });
    

    您甚至可以将 MotionEvent 传递给怪物。 (或者,如果您想要单一类型的 TouchListener,您可以将视图和事件都传递给怪物,但您会丢失有关哪个开关是哪个开关的信息。)

    【讨论】:

      【解决方案2】:

      由于您在顶视图组 LinearLayout 上使用了 ontouchlistener 来处理运动事件,如果 ontouchlistener 的返回值为 true,则不会将事件分派到任何其他目标。所以可能你需要使用丑陋的方法。我目前正在处理这个问题,发现它真的很烦人。

      否则,根据需要为每个子视图设置 ontouchlistener。

      【讨论】:

      • 是的,我想除了丑陋的方式之外别无他法。好吧,只要它有效。谢谢!
      【解决方案3】:

      如果可以,请在基本布局(线性或其他)和子视图下使用 ListView 或 GridView。

      那么……

      int pos = getGridView().pointToPosition((int) me.getX(), (int) me.getY());

      查看 v = getGridView().getChildAt(pos);

      你也可以听孩子仔细管理你在处理时返回的布尔值。

      【讨论】:

      【解决方案4】:

      给孩子一个 id 并从父视图中使用 parentView.findViewById(R.id.childviewid);

      【讨论】:

      • 感谢您的回复。但我正在寻找一种从坐标获得视图的方法。实际上,对于我提到的“丑陋解决方案”,您建议的方式是 - 我保留所有子 ID 的列表,然后查询所有子 ID 以查看坐标是否落在其中一个上。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 2011-06-05
      • 2018-04-08
      相关资源
      最近更新 更多