Rot*_*tem 5 android touch scrollview motionevent
我一直试图弄清楚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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我点击屏幕上的任何地方时,我得到这个日志:
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
Run Code Online (Sandbox Code Playgroud)
这意味着触摸事件没有让位于scrollview内部的内部布局.但是当我将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
Run Code Online (Sandbox Code Playgroud)
我查看了ScrollView类的源代码,它覆盖的唯一与触摸相关的方法就是我自己压倒的方法.所以我不明白LinearLayout和ScrollView的行为之间有什么区别.
Lui*_*uis 10
也许你已经弄明白为什么上面的行为,但万一你不这样做,这就是原因.
概观
的onInterceptTouchEvent()被称为自顶向下(从父到子),使得一个视图被儿童正在处理之前拦截运动事件.
在onTouchEvent()被称为自底向上(从子到父),直到其中一个消费它和循环共完成.
一个ScrollView拦截MotionEvent,检查它是否应该将它们传递给孩子之前滚动视图.如果应该执行滚动,则会消耗该事件并且子视图不会看到任何内容.
在这种情况下LinearLayout,没有理由在此期间消耗该事件onInterceptTouchEvent(),并且始终将其传递给子视图.
您的代码中发生了什么
因为MyInnerLayout是空的ScrollView,总是消耗着MotionEvent.
例如,如果您设置内部布局背景,如下所示:
MyInnerLayout inner = new MyInnerLayout(getApplicationContext());
inner.setBackground(getResources().getDrawable(R.drawable.ic_launcher));
MyLayout layout = new MyLayout(getApplicationContext());
Run Code Online (Sandbox Code Playgroud)
你会看到,如果你触摸背景图像,事件就会到达孩子身上.如果您在背景图像外触摸,则该事件将被消耗ScrollView.
希望这可以帮助.
问候.
| 归档时间: |
|
| 查看次数: |
12305 次 |
| 最近记录: |