我一直试图弄清楚 Android 中 ScrollViews 中 MotionEvents 的行为,但有些东西我无法弄清楚。
作为一个例子,我制作了一个 Activity,里面有一个 ScrollView,而 ScrollView 里面有一个 LinearLayout。我实现了自己的类来控制与触摸相关的功能:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyInnerLayout inner = new MyInnerLayout(getApplicationContext());
MyLayout layout = new MyLayout(getApplicationContext());
layout.addView(inner,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
setContentView(layout);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("scrollview","activity dispatchTouchEvent "+ev.getAction());
return super.dispatchTouchEvent(ev);
};
@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.i("scrollview","activity on touch "+ev.getAction());
return super.onTouchEvent(ev);
}
public class MyLayout extends ScrollView {
public MyLayout(Context context) {
super(context);
}
@Override
public boolean dispatchKeyEvent(KeyEvent ev) {
Log.i("scrollview","layout dispatchKeyEvent "+ev.getAction());
return super.dispatchKeyEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i("scrollview","layout onInterceptTouchEvent "+ev.getAction());
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.i("scrollview","layout on touch "+ev.getAction());
return false;
}
}
public class MyInnerLayout extends LinearLayout{
public MyInnerLayout(Context context) {
super(context);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("scrollview","inner layout dispatchTouchEvent "+ev.getAction());
return true;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i("scrollview","inner layout onInterceptTouchEvent "+ev.getAction());
return true;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.i("scrollview","inner layout on touch "+ev.getAction());
return true;
}
}
}
当我单击屏幕上的任意位置时,我会收到以下日志:
10-14 18:11:48.631: I/scrollview(14906): activity dispatchTouchEvent 0
10-14 18:11:48.631: I/scrollview(14906): layout onInterceptTouchEvent 0
10-14 18:11:48.631: I/scrollview(14906): layout on touch 0
10-14 18:11:48.631: I/scrollview(14906): activity on touch 0
10-14 18:11:48.647: I/scrollview(14906): activity dispatchTouchEvent 1
10-14 18:11:48.647: I/scrollview(14906): activity on touch 1
这意味着触摸事件没有进入滚动视图内的内部布局。但是,当我将 ScrollView 更改为 LinearLayout 时(只需在扩展中更改它),事件就会下降到内部布局:
10-14 18:24:08.975: I/scrollview(15115): activity dispatchTouchEvent 0
10-14 18:24:08.975: I/scrollview(15115): layout onInterceptTouchEvent 0
10-14 18:24:08.975: I/scrollview(15115): inner layout dispatchTouchEvent 0
10-14 18:24:09.045: I/scrollview(15115): activity dispatchTouchEvent 1
10-14 18:24:09.045: I/scrollview(15115): layout onInterceptTouchEvent 1
10-14 18:24:09.045: I/scrollview(15115): inner layout dispatchTouchEvent 1
我查看了 ScrollView 类的源代码,它覆盖的唯一与触摸相关的方法是我自己覆盖的方法。所以我不明白 LinearLayout 和 ScrollView 的行为有什么区别。