繁体   English   中英

如何查找MotionEvent ACTION_CANCEL的源视图

[英]How to find the source view of a MotionEvent ACTION_CANCEL

如何找到导致MotionEvent ACTION_CANCEL的视图? 我有一个接收ACTION_CANCEL的视图“A”,我不希望这种情况发生。 在某处,视图“B”正在“消耗”MotionEvent。 我希望有办法找出谁是“B”,这样我才能解决这个错误的问题。

我已经尝试查看我的代码中的各种OnTouchEvent()和OnInterceptTouchEvent()处理程序,但还没有找到罪魁祸首。

我还在有问题的ACTION_CANCEL上设置了一个断点但是我无法识别可能代表“B”的MotionEvent中的任何内容。

如果父母正在拦截运动事件,防止这种情况的唯一方法是阻止父母拦截该事件。 这可以通过两种方式很好地管理。

如果没有看到具体的代码并想要一个通用的解决方案,我建议如下。

我建议通过管理家长和孩子来管理你的触摸事件
requestDisallowInterceptTouchEvent(boolean)

受影响的视图A,B中的每个视图/视图组的onInterceptTouchEvent(android.view.MotionEvent)事件处理程序。

通过禁止孩子中的父级拦截,这有助于您捕捉未考虑的父级拦截,并且还可以在一个父级内定制和更改子元素。

这必须从您的view / viewGroup的最高父级进行管理,并通过所有父级和子级关系进行管理。

检查列表视图,具有内置触摸事件的任何元素。

android.com/training/gestures/viewgroup

在找到拦截事件的违规视图方面,除了以下逻辑之外无法回答:

遍历每个父级到子级/父级到子级视图。 有条不紊地检查每个视图/视图组中的ontouch处理,如图中所示。

查看图表

这些答案中有更多细节:
https://stackoverflow.com/a/30966413/3956566
https://stackoverflow.com/a/6384443/3956566

我相信你明白这一点,但对我来说,这是最简单的解决方案。

除此之外,我们还需要查看您的代码以对其进行故障排除。

如果我的问题正确,您可能在父级中接收ACTION_CANCEL ,您需要找到该视图。 给定事件X和Y,您可以在ACTION_CANCEL发生的第一时间找到包含这些坐标的视图。 尝试使用顶级父级(android.R.id.content)或您正在处理的ViewGroup调用此方法。

private View findViewAt(View contentView, int eventX, int eventY) {
            ArrayList<View> unvisited = new ArrayList<View>();
            unvisited.add(contentView);
            while (!unvisited.isEmpty()) {
                View child = unvisited.remove(0);
                if(isViewContains(child, eventX, eventY) {
                    Log.i(TAG, "view found! ");
                    unvisited.clear();
                    return child;
                }
                if (!(child instanceof ViewGroup)){
                    continue;
                }
                ViewGroup group = (ViewGroup) child;
                final int childCount = group.getChildCount();
                for (int i=0; i< childCount; i++){
                    unvisited.add(group.getChildAt(i));
                }
            }
      return null;
    }


private boolean isViewContains(View view, int eventX, int eventY) {
    int[] location = new int[2];
    view.getLocationOnScreen(location);
    int x = location[0];
    int y = location[1];
    int width = view.getWidth();
    int height = view.getHeight();
    return eventX < x || eventX > x + width || eventY < y || eventY > y + height;
}

根据我的经验,一个使A视图收到ACTION_CANCEL事件的案例是在用户触摸A之后他们将手指拖出A区域,如果你遇到这种情况,添加一个方法来检查dispatchTouchEvent()上的位置可以救命。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM