在Android中将触摸事件传递给父View的onTouchListener

4

我有一个列表视图,其项目是一个线性布局,其中包含一个按钮作为其子视图。我希望线性布局的onTouchLIstener能够工作。我不想使用onInterceptTouchEvent。是否有一种方法可以将触摸从按钮传递给父列表视图。我尝试了这个 - 从按钮的onTouchListener返回true。

private View.OnTouchListener buttonListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            Log.i(TAG, "Button On Touch");
            return true;
        }
};

但是这种方法并不起作用。它无法将触摸事件传递给LinearLayout的onTouchListener
一定有一种方法可以使其正常工作。

尝试返回 false 而不是其他值 - Evan
@Evan:不行,还是不起作用。父级的onTouchListener中的日志什么也没有显示。 - Ashwin
1
你需要使用onInterceptTouchEvent,这是它的作用。 - pskink
@pskink:使用onInterceptTouchEvent 的问题是我必须使用扩展LinearLayout的自定义布局。而且我希望代码驻留在ListAdaper类中,这在onInterceptTouchEvent中是不可能的,因为它只能被重写。是否可能将触摸事件从OnInterceptTouchEvent传递给OnTouchListener? - Ashwin
2个回答

11
ViewGroup的事件链如下:调用dispatchEvent后,dispatchEvent会调用onInterceptTouchEvent。如果onInterceptTouchEvent返回false,则触摸事件会传递给ViewGroup的子视图。如果任何一个子视图消耗了事件(在这种情况下,按钮消耗了事件),即它们返回true,则不会将motionevent传递给其他方法。由于按钮是可点击的,因此在这种情况下返回true。

如果onInterceptTouchEvent方法返回true,则不会将运动事件传递给子视图,而是调用该ViewGroup的onTouchListener或onTouch方法。
因此,为了将触摸事件传递给父ViewGroup的onTouchListener,请确保在父ViewGroup的onInterceptTouchEvent方法中返回true。您不必覆盖onDispatchTouchEvent()方法。
@Override
    public boolean onInterceptTouchEvent(MotionEvent motionEvent) {

        Log.i(TAG,"PARENT.onInterceptTouchEvent");

        return true;
}

如需了解有关触摸导航的详细信息,请参阅此 Stack 帖子


3

将按钮的可点击属性设置为false,使用以下代码:

button.setClickable(false);

然后在按钮的 onTouch 中:

return false;

注意:这种行为只适用于按钮(以及任何其他设置了clickable属性为true的视图),即使您从onTouch返回false,它也不会将事件传播到父级,onClick方法仍然会被调用。


编辑:另一种方法是扩展ListView类并重写onInterceptTouch方法:

public class CustomListView extends ListView {
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // here you can listen for button touch events
    }
}

但我希望按钮可以被点击。 - Ashwin
“这个行为是特定于按钮的”是什么意思?其他视图不会发生吗? - Ashwin
特定于按钮,因为它默认是可点击的。任何其他具有设置为“true”的clickable属性的视图将与按钮行为相同。(我重新编辑以澄清) - semsamot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接