自定义ViewGroup.dispatchTouchEvent()无法正常工作

And*_*nko 2 android android-custom-view

我正在开发自定义ViewGroup.它是某种径向菜单(类似于Android相机应用程序中的选项菜单).

我设法正确地布置和画儿童.我要做的另一件事是覆盖触摸事件调度:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    for (int i=0; i<getChildCount(); i++) {
        CircularView child=(CircularView) getChildAt(i);
        if (child.viewMetrics.containsPoint(ev.getX(), ev.getY())) {
            child.dispatchTouchEvent(ev);
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

如果事件坐标属于任何一个(child.viewMetrics.containsPoint()方法调用,双重检查,正常工作),我遍历子节点并调度事件.

似乎工作,但它并不完美.我注意到了这个问题:当我点击时,握住我的手指并稍微移动它,点击就会中断.这是演示.

我查看了超类的实现,并且有很多代码.我的第一个想法是复制它,但它取决于许多私人课程.

如何确保触摸事件调度正常工作?(不仅是点击,还有所有其他手势?)如果没有简单的方法可以做到这一点,我将非常感谢有关移植默认实现的任何意见或建议或任何有关该主题的有用信息的链接.

Mar*_*los 9

在调度touchEvents时,您应该将位置偏移到视图left/top.

导致单击800x400的滚动视图(当scrollX = 200时)表示您正在触摸1000x400的视图,然后您知道哪个视图已被触摸,其界限类似于ltrb(950,0,1050,600 ),要正确调度它,您应该在调度时偏移x,y的值,这意味着您将MotionEvent(50,400)发送到子视图.

该视图将正确处理touchEvent并将其发送给子项或自行处理.

并且一个提示是,有时是一个视图,而调度将通过某个值设置事件,并且下一个MotionEvent将不再等于循环后的原始事件,因此您应该向子项发送一个副本.

在简历中,它是这样的:

MotionEvent cp = MotionEvent.obtain(event);
cp.offset(-child.getLeft(), -child.getTop());
boolean consumed = child.dispatchTouchEvent(cp);
cp.recycle();
return consumed;
Run Code Online (Sandbox Code Playgroud)

我已经覆盖了几个类的dispatchTouchEvent/onTouchEvent,这确实可以正常工作.

另外:我确实观看过youtube视频,可能有些视图正在拦截触摸事件并向您的视图发送ACTION_CANCEL,这就是您放弃事件的原因.(这发生在我身上,这就是为什么我覆盖所有View类的dispatch/onTouch)