覆盖onTouchEvent与ScrollView竞争

brk*_*rk3 16 user-interface android drag-and-drop scrollview

从简单的概述我有一个自定义视图,其中包含用户可以拖动和调整大小的一些位图.

我这样做的方式是相当标准的,因为我在我的CustomView中重写onTouchEvent并检查用户是否在图像中触摸等.

当我想将这个CustomView放在ScrollView中时,我的问题出现了.这可行,但ScrollView和CustomView似乎竞争MotionEvents,即当我尝试拖动图像时,它移动缓慢或视图滚动.

我想我可能需要扩展ScrollView,以便我可以覆盖onInterceptTouchEvent并让它知道用户是否在图像的范围内而不是尝试滚动.但是,因为ScrollView在层次结构中更高,我将如何访问CustomView的当前状态?

有没有更好的办法?

ada*_*amp 41

通常Android会在这种情况下使用长按来开始拖动,因为它有助于消除用户打算拖动项目时的歧义,而不是滚动项目的容器.但是,如果用户开始拖动项目时有明确的信号,请在getParent().requestDisallowInterceptTouchEvent(true)知道用户开始拖动时尝试自定义视图.(文档此方法在这里.)这将防止滚动型截获触摸事件,直到当前手势结束.

  • 非常感谢你,这很有用!SO上有一些很棒的API知识:) (2认同)

Sal*_*lab 9

找不到任何解决方案对我来说都是"开箱即用",可能是因为我的自定义视图扩展了View而不是ViewGroup,因此我无法实现onInterceptTouchEvent.

还打电话getParent().requestDisallowInterceptTouchEvent(true)是投掷NPE,或者什么都不做.

最后,这就是我解决问题的方法:当您的视图处理事件时,
在您的自定义onTouchEvent调用中requestDisallow....例如:

@Override
public boolean onTouchEvent(MotionEvent event) {
    Point pt = new Point( (int)event.getX(), (int)event.getY() );
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        if (/*this is an interesting event my View will handle*/) {
            // here is the fix! now without NPE
            if (getParent() != null) {
                getParent().requestDisallowInterceptTouchEvent(true);
            }

            clicked_on_image = true;
        }
    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
        if (clicked_on_image) {
            //do stuff, drag the image or whatever
        }
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
        clicked_on_image = false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

现在我的自定义视图工作正常,处理一些事件并让scrollView捕获我们不关心的事件.在这里找到解决方案:http://android-devblog.blogspot.com.es/2011/01/scrolling-inside-scrollview.html

希望能帮助到你.