Android 如何在父视图的触摸侦听器中使用子视图的触摸事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10042142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to consume child view's touch event in parent view's touchlistener?
提问by Sock
In my application I want to get the touch event of all child view's in my parent view's onTouchListener
but I could not get this.
在我的应用程序中,我想获得父视图中所有子视图的触摸事件,onTouchListener
但我无法获得。
Example:
例子:
In my activity's view I have one frame layout which has some buttons and edittexts in it. So whenever I touch buttons or edit text I want to get this touch event in framlayout'sonTouchListeners
.
在我的活动视图中,我有一个框架布局,其中包含一些按钮和编辑文本。因此,每当我触摸按钮或编辑文本时,我都希望在framlayout 的onTouchListeners
.
Here is my code..
这是我的代码..
Activity:
活动:
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>
Problem:So whenver I touch the buttons or edittext I can't get touch co-ordition in my frame layout's onTouchListener (It's not called).
问题:所以每当我触摸按钮或编辑文本时,我都无法在我的框架布局的 onTouchListener(它没有被调用)中获得触摸协调。
Note:I don't want to add separate onTouchListener for all childViews.
注意:我不想为所有 childView 添加单独的 onTouchListener。
Thanks in advance.
提前致谢。
回答by dokkaebi
You could accomplish that by overriding dispatchTouchEvent
in the layout.
您可以通过覆盖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);
}
}
Then use that layout in place of the usual FrameLayout:
然后使用该布局代替通常的 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">
...
You could also skip the super call entirely if you need to prevent child views from receiving the event, but I think this would be rare. If you need to recreate some, but not all, of the default functionality, there is a lot to rewrite:
如果您需要阻止子视图接收事件,您也可以完全跳过超级调用,但我认为这种情况很少见。如果您需要重新创建一些(但不是全部)默认功能,则需要重写很多内容:
回答by Mehmed
I have tried similar design with (only one onTouch Listener on a root FrameLayout) and it worked. I get all the points provided that onTouch return true instead of false. Otherwise, I just get the first point. I couldn't find out the reason for this "return" issue since I expect opposite behaviour.
我已经尝试过类似的设计(在根 FrameLayout 上只有一个 onTouch Listener)并且它起作用了。只要 onTouch 返回 true 而不是 false,我就得到了所有的分数。否则,我只得到第一点。我无法找出这个“退货”问题的原因,因为我预计会有相反的行为。
However, based on my experience, if you set any of child view clickable, then its parent's onTouch will not work. If you have another solution and if you share, that would be great.
但是,根据我的经验,如果您将任何子视图设置为可点击,那么其父视图的 onTouch 将不起作用。如果您有其他解决方案并分享,那就太好了。
回答by android developer
2 solutions:
2个解决方案:
Use onInterceptTouchEventon the ViewGroup, as shown here
Avoid having the layout handle the touch events, and have a view that is the child view of the layout, that covers its whole size, to handle the touch events.
It's not as efficient as extending classes, but it is much easier and doesn't require to create new files/classes.
example:
Just add the touch events to the view, and it will handle them instead of any of the other views.
使用onInterceptTouchEvent的ViewGroup中,如图所示这里
避免让布局处理触摸事件,并有一个视图是布局的子视图,覆盖其整个大小,来处理触摸事件。
它不像扩展类那样有效,但它更容易并且不需要创建新的文件/类。
例子:
只需将触摸事件添加到视图中,它就会处理它们而不是任何其他视图。
回答by hemalatha.marikumar
It can be achieved by using "onInterceptTouchEvent". Please try this,it may work
可以通过使用“onInterceptTouchEvent”来实现。请试试这个,它可能会工作
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
onTouchEvent(ev);
return false;
}