如何找到导致MotionEvent ACTION_CANCEL的视图?我有一个观点" A"正在接受ACTION_CANCEL,我不希望这种情况发生。在某个地方,一个观点" B"是"消费" MotionEvent。我希望有办法找出谁是" B"所以我可以解决这个错误的功能。
我已经尝试通过我的代码查看各种OnTouchEvent()和OnInterceptTouchEvent()处理程序,但还没有找到罪魁祸首。
我还在有问题的ACTION_CANCEL上设置了一个断点,但我无法识别可能代表" B"的MotionEvent中的任何内容。
答案 0 :(得分:6)
如果父母正在拦截运动事件,防止这种情况的唯一方法是阻止父母进行 拦截那个事件。这可以通过两种方式很好地管理。
如果没有看到具体的代码并想要一个通用的解决方案,我建议如下。
我建议您通过管理家长和孩子来管理您的触摸事件 requestDisallowInterceptTouchEvent(boolean)和
受影响的视图A,B C中每个视图/视图组的onInterceptTouchEvent(android.view.MotionEvent)个事件处理程序。
通过禁止孩子的父母拦截,这有助于你抓住父母拦截你 没有考虑到,并且还要从一个父母中定制和改变子元素。
这必须从您的视图/ viewGroup的最高父级进行管理,并通过所有父级和 孩子的关系。
检查列表视图,具有内置触摸事件的任何元素。
android.com/training/gestures/viewgroup
在查找拦截事件的违规视图方面,除了以下逻辑之外无法回答:
浏览每个父级到子级/父级到子级视图。有条不紊地检查每个视图/视图组中的ontouch处理 如我的图所示。
这些答案中有更多细节:
https://stackoverflow.com/a/30966413/3956566
https://stackoverflow.com/a/6384443/3956566
我确定你理解这一点,但对我来说,这是最简单的解决方案。
除此之外,我们还需要查看您的代码以对其进行故障排除。
答案 1 :(得分:2)
如果我的问题正确无误,您可能会在父母中收到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;
}
答案 2 :(得分:1)
根据我的经验,使A视图收到ACTION_CANCEL事件的案例是在用户触摸A并且他们将手指拖出A区域之后,如果您遇到这种情况,请添加方法以检查dispatchTouchEvent上的位置()可以提供帮助。