目前以下是我的应用程序的布局:
LinearLayout
----Button
----ScrollView
----RelativeLayout
----EditText
我在所有这些上创建了一个透明的LinearLayout,实现了OnTouchListener并在OnTouch()内部,返回false。因此,所有控件都移动到childrens以下。但是在LinearLayout上,我无法处理ACTION_MOVE操作,因为此布局不会使用MotionEvent对象。有什么办法可以在父视图和子视图中检测到所有触摸事件吗?
答案 0 :(得分:2)
根据我的经验,dispatchTouchEvent()
方法不应该被覆盖,因为它很难控制。我的建议是onInterceptTouchEvent()
方法。 Android覆盖不支持此选项。您可以通过创建自己的View来劫持它,这是一个从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_DOWN返回false,则认为父级尚未窃取此触摸事件,并检查如果它的孩子被实施onTouch()
。因此,只要孩子不打电话requestDisallowInterceptTouchEvent(true)
,父母仍然可以在onInterceptTouchEvent()
中处理此触摸事件,并且孩子可以在自己的onTouch()
事件中处理相同的触摸事件。但是,有时您需要考虑父母的onTouch()
事件,以防没有孩子处理触摸事件,所以父母可以照顾它。答案 1 :(得分:1)
您可以通过覆盖布局中的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);
}
}
然后使用该布局代替通常的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">
...
如果你需要防止孩子,你也可以完全跳过超级电话 收到活动的意见,但我认为这很少见。
此答案基于 Romain家伙答案的reference。