同时检测父视图和子视图的Android触摸事件

同时检测父视图和子视图的Android触摸事件,android,android-layout,android-activity,touch-event,Android,Android Layout,Android Activity,Touch Event,目前,以下是我的应用程序的布局: LinearLayout ----Button ----ScrollView ----RelativeLayout ----EditText 我在所有这些之上创建了一个透明的LinearLayout,在OnTouchListener中实现,在OnTouch()中返回false。所以,所有控件都移动到子控件下方。但在L

目前,以下是我的应用程序的布局:

       LinearLayout
            ----Button
               ----ScrollView
                  ----RelativeLayout
                     ----EditText

我在所有这些之上创建了一个透明的LinearLayout,在OnTouchListener中实现,在OnTouch()中返回false。所以,所有控件都移动到子控件下方。但在LinearLayout上,我无法处理动作\移动动作,因为此布局不使用MotionEvent对象。是否有任何方法可以检测父视图和子视图中的所有触摸事件?

您可以通过覆盖布局中的
dispatchTouchEvent
来实现这一点

public class MyFrameLayout extends LinearLayout {
    @Override
    public boolean dispatchTouchEvent(MotionEvent e) {
        // do what you need to with the event, and then...
        return super.dispatchTouchEvent(e);
    }
}
然后使用该布局代替通常的框架布局:

    <com.example.android.MyFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="10dip"
        android:id="@+id/rootview">

  ...

...
如果你需要防止孩子怀孕,你也可以完全跳过超级呼叫 收到活动的意见,但我认为这将是罕见的


这个答案基于Romain guy的答案。

根据我的经验,
dispatchTouchEvent()
方法不应该被重写,因为它有点难以控制。我的建议是
onInterceptTouchEvent()
方法。Android不支持覆盖此选项。您可以通过创建自己的视图来劫持它,下面是一个从RelativeLayout扩展而来的片段:

public class InterceptTouchRelativeLayout extends RelativeLayout{

public interface OnInterceptTouchListener{
    boolean onInterceptTouch(MotionEvent ev);
}

private OnInterceptTouchListener onInterceptTouchListener;

public InterceptTouchRelativeLayout(Context context) {
    super(context);
}

public InterceptTouchRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public InterceptTouchRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return onInterceptTouchListener.onInterceptTouch(ev);
}

public void setOnInterceptTouchListener(OnInterceptTouchListener onInterceptTouchListener) {
    this.onInterceptTouchListener = onInterceptTouchListener;
}
}

像往常一样使用它

myView.setOnInterceptTouchListener(new InterceptTouchRelativeLayout.OnInterceptTouchListener() {
        @Override
        public boolean onInterceptTouch(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    // Parent didn't steal this touch event if return false this case.
                    return false;

                case MotionEvent.ACTION_MOVE:
                    // Parent didn't steal this touch event if return false this case.
                    return false;

                case MotionEvent.ACTION_UP:
                    // Parent didn't steal this touch event if return false this case. However, please notice, it's too late for the parent to steal this touch event at this time, it won't work anymore.
                    return true;
            }

            return false;
        }
    });
无论如何,我的建议是更多地研究视图/视图组控件触摸事件的流程。下面解释了
onInterceptTouchEvent()
如何为您的目的而工作:

  • 当在父对象的子对象所在的位置触摸父对象时,将调用
    onInterceptTouchEvent()
    ,如果我们在ACTION\u DOWN返回false,则将认为父对象尚未窃取此触摸事件,并检查其子对象是否已实现
    onTouch()
    。因此,只要孩子不调用
    requestDisallowWinterCeptTouchEvent(true)
    ,父母仍然可以在
    onInterceptTouchEvent()
    中处理此触摸事件,孩子也可以在自己的
    onTouch()
    事件中处理相同的触摸事件。但是,有时你需要考虑处理父母的<代码> OnTouChh()/Cyto>事件,以防孩子没有处理触摸事件,这样父母就可以照看它。
我已经尝试过了,但仍然只有第一次调用dispatchTouchEvent。在此之后,MotionEvent对象被任何子布局使用,并且不再调用它。是否同时在父布局和子布局中处理该事件?是..我需要同时在两个布局中处理。实际上,我希望所有动作都能从外部活动中向上、向下移动事件。我使用它作为包装框架布局,覆盖内联方法,然后将实际膨胀的视图添加到其中。很好!