如何处理子视图中的点击事件,以及父ViewGroup中的触摸事件?

7
在我的布局中,我有以下结构:
--RelativeLayout
  |
  --FrameLayout
    |
    --Button, EditText...

我希望能在RelativeLayout和FrameLayout中处理触摸事件,所以我在这两个视图组中设置了onTouchListener。但只有RelativeLayout中的触摸事件被捕捉到。
为了解决这个问题,我编写了自己的CustomRelativeLayout,并重写了onInterceptTouchEvent方法,现在子ViewGroup(FrameLayout)中的点击事件被捕捉到,但是按钮和其他视图的点击没有任何效果。
在我的自定义布局中,我有以下内容:
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return true;
}
3个回答

7
你需要为每个子元素重写onInterceptTouchEvent()方法,否则它将保留父级的onTouchEvent方法。
参考链接:在ViewGroup中拦截触摸事件
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    /*
    * This method JUST determines whether we want to intercept the motion.
    * If we return true, onTouchEvent will be called and we do the actual
    * scrolling there.
    */
...
    // In general, we don't want to intercept touch events. They should be 
    // handled by the child view.
    return false;
}

你需要返回false以使子元素处理该事件,否则你将其返回给父元素。

2
假设我想仅重写触摸事件以处理某些子项,我可以在此函数内做些什么以使其工作?我的意思是,对于某些子项,它将像往常一样工作,而对于其他子项,则由父视图决定是否接收触摸事件。 - android developer

1

我能够用下面的代码解决这个问题:

步骤1:在onCreate()方法上方声明EditText。

public EditText etMyEdit;

步骤2:在onResume()方法中,配置结束。
etMyEdit = (EditText) findViewById (R.id.editText);

etMyEdit.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            v.getParent().requestDisallowInterceptTouchEvent(true);
            switch (event.getAction() & MotionEvent.ACTION_MASK){
                case MotionEvent.ACTION_UP:
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                    return false;
            }
            return false;
        }
    });

希望能对某些人有所帮助!

1
你的自定义解决方案将从相对布局中的任何位置捕获触摸事件,因为重写的方法设置为始终抛出true。
针对您的要求,我认为最好使用onClick方法而不是使用onTouch。
OnTouch方法在每个TouchEvent上调用不同的线程,我想这就是您问题的原因。
与其处理这些事件,还不如尝试使用onClick方法。

谢谢,但是即使我在这两个视图组中都设置了onClick,只有第一个RelativeLayout中的点击被处理。 - androidevil
1
分享代码肯定会让事情更清晰。 - testuserx

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