如何在父视图的touchlistener中使用子视图的触摸事件?

在我的应用程序中,我想要在我的父视图的onTouchListener获取所有子视图的触摸事件,但是我无法得到它。

例:

在我的活动视图中,我有一个框架布局,其中有一些button和edittexts。 所以,只要我触摸button或编辑文本,我想在framlayout的 onTouchListeners获得这个触摸事件。

这是我的代码

活动:

 private FrameLayout rootView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); rootView = (FrameLayout) findViewById(R.id.rootview); rootView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Log.e("Touch Event: ", " X: " + event.getX() + " Y: " + event.getY()); return false; } }); } 

main.xml中:

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout 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"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@android:color/white" android:orientation="vertical" android:layout_gravity="center" android:padding="10dip"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:padding="4dp" android:text="Login" android:textColor="@android:color/black" android:textSize="16dp" android:textStyle="bold" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Username" android:textColor="@android:color/black" android:textSize="14dp" android:textStyle="bold" /> <EditText android:id="@+id/edttextusername" android:layout_width="fill_parent" android:layout_height="wrap_content" android:imeOptions="flagNoExtractUi" android:singleLine="true" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Password" android:textColor="@android:color/black" android:textSize="14dp" android:textStyle="bold" /> <EditText android:id="@+id/edttextpassword" android:layout_width="fill_parent" android:layout_height="wrap_content" android:imeOptions="flagNoExtractUi" android:password="true" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:orientation="horizontal" android:padding="10dp" > <Button android:id="@+id/btnlogin" android:layout_width="0dip" android:layout_height="40dip" android:layout_marginRight="5dp" android:layout_weight="1" android:enabled="false" android:text="Login" android:padding="5dip" android:textColor="@android:color/black" android:textStyle="bold" /> <Button android:id="@+id/btncall" android:layout_width="0dip" android:layout_height="40dip" android:layout_marginLeft="5dp" android:layout_weight="1" android:padding="5dip" android:text="Cancel" android:textColor="@android:color/black" android:textStyle="bold" /> </LinearLayout> </LinearLayout> </FrameLayout> 

问题:所以当我触摸button或编辑文本时,我无法在我的框架布局的onTouchListener(未调用)中获得触摸协调。

注意:我不想为所有childView添加单独的onTouchListener。

提前致谢。

Solutions Collecting From Web of "如何在父视图的touchlistener中使用子视图的触摸事件?"

您可以通过在布局中重写dispatchTouchEvent来完成此操作。

 public class MyFrameLayout extends FrameLayout { @Override public boolean dispatchTouchEvent(MotionEvent e) { // do what you need to with the event, and then... return super.dispatchTouchEvent(e); } } 

然后使用该布局来代替通常的FrameLayout:

 <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"> ... 

如果您需要阻止子视图接收事件,您也可以完全跳过超级呼叫,但我认为这很less见。 如果您需要重新创build一些但不是全部的默认function,则需要重新编写很多内容:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/view/ViewGroup.java#ViewGroup.dispatchTouchEvent%28android.view.MotionEvent% 29

我曾尝试类似的devise(根FrameLayout上只有一个onTouch监听器),它的工作。 我得到所有的观点,onTouch返回true而不是false。 否则,我只是得到第一点。 我无法find这个“回报”问题的原因,因为我期望有相反的行为。

但是根据我的经验,如果你设置了任何一个子视图可点击的话,那么它的父级的onTouch将不起作用。 如果你有另一个解决scheme,如果你分享,这将是伟大的。

2解决scheme:

  1. 在ViewGroup上使用onInterceptTouchEvent ,如下所示

  2. 避免让布局处理触摸事件,并且有一个视图是布局的子视图,覆盖整个大小,以处理触摸事件。

    它不像扩展类那样高效,但是它更容易,不需要创build新的文件/类。

    例:

    只需将触摸事件添加到视图,它将处理它们而不是任何其他视图。

它可以通过使用“onInterceptTouchEvent”来实现。 请尝试这个,它可能工作

 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { onTouchEvent(ev); return false; }