关于android 的事件分发机制
2017-08-03 11:16
281 查看
android 关于事件分发的三个方法:
dispatchTouchEvent代表事件分发,返回值为true或false都表示不分发,返回super.dispatchTouchEvent表示将事件分发下去
onInterceptTouchEven代表事件拦截(ViewGroup特有的事件),返回值为true表示拦截事件,交给ViewGroup的OnTouchEvent处理,返回值为false表示交给子view的dispatchTouchEvent进行事件分发
onTouchEvent代表事件消费,返回值为true表示消费,返回值为false表示不消费,该事件将交给父控件的onTouchEvent进行处理
首先在dispatchTouchEvent中最先执行的就是onTouch方法,而onClick的调用是在onTouchEvent(event)方法中,因此onTouch肯定是要优先于onClick执行的。
而如果在onTouch方法里返回了true,就会让dispatchTouchEvent方法直接返回true,不会再继续往下执行。
下附代码说明,有兴趣的可以直接跑一下验证
以上面这段代码为例子,如果我重写了LinearLayout中的onInterceptTouchEvent并返回true
改成
然后添加一句代码
运行之后,btn不会触发点击事件,因为事件被MyLayout拦截了,转而触发MyLayout的点击事件,如果这个时候设置onTouch事件返回true,那么连MyLayout的点击事件
4000
也不会触发,因为OnTouchEvent没有接受到事件,在OnTouchEvent内部被调用的OnClick事件自然也不会触发
最后再补充一句,ViewGroup和View都有dispatchTouchEvent方法,如果在ViewGroup里面dispatchTouchEvent的返回值为true,那么事件就不会分发下去,在我这个例子里面就是没有触发btn的点击事件
dispatchTouchEvent代表事件分发,返回值为true或false都表示不分发,返回super.dispatchTouchEvent表示将事件分发下去
onInterceptTouchEven代表事件拦截(ViewGroup特有的事件),返回值为true表示拦截事件,交给ViewGroup的OnTouchEvent处理,返回值为false表示交给子view的dispatchTouchEvent进行事件分发
onTouchEvent代表事件消费,返回值为true表示消费,返回值为false表示不消费,该事件将交给父控件的onTouchEvent进行处理
首先在dispatchTouchEvent中最先执行的就是onTouch方法,而onClick的调用是在onTouchEvent(event)方法中,因此onTouch肯定是要优先于onClick执行的。
而如果在onTouch方法里返回了true,就会让dispatchTouchEvent方法直接返回true,不会再继续往下执行。
下附代码说明,有兴趣的可以直接跑一下验证
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); LinearLayout ll = (LinearLayout) findViewById(R.id.ll); Button btn = (Button) findViewById(R.id.btn); ll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "LinearLayout: "); } }); ll.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return false; } }); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "Button: "); } }); btn.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return false; } }); } }
以上面这段代码为例子,如果我重写了LinearLayout中的onInterceptTouchEvent并返回true
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.e(TAG, "MyLayout onInterceptTouchEvent default return " + super.onInterceptTouchEvent(ev)); return super.onInterceptTouchEvent(ev); }
改成
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.e(TAG, "MyLayout onInterceptTouchEvent default return " + super.onInterceptTouchEvent(ev)); return true; }
然后添加一句代码
btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "Button: "); btn.setText( "Button: "); } });
运行之后,btn不会触发点击事件,因为事件被MyLayout拦截了,转而触发MyLayout的点击事件,如果这个时候设置onTouch事件返回true,那么连MyLayout的点击事件
4000
也不会触发,因为OnTouchEvent没有接受到事件,在OnTouchEvent内部被调用的OnClick事件自然也不会触发
最后再补充一句,ViewGroup和View都有dispatchTouchEvent方法,如果在ViewGroup里面dispatchTouchEvent的返回值为true,那么事件就不会分发下去,在我这个例子里面就是没有触发btn的点击事件
相关文章推荐
- Android中Touch事件分发机制-关于dispatchTouchEvent等方法的研究
- android-----关于事件分发机制中几点困惑测试
- 关于Android事件分发机制一些要注意的问题
- 关于Android的事件分发机制
- 【Android View事件分发机制】关于拦截事件的注意点
- 关于Android 事件分发机制的学习
- 关于Android的Touch事件的分发机制
- 关于android中的事件分发机制,点击事件分发机制详解
- 关于android事件分发机制
- 关于android事件分发机制
- 关于Android事件分发机制的理解
- Android 事件分发机制详解
- Android事件分发及拦截机制
- Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
- Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
- 图片会说话系列之Android事件的分发传递机制
- Android事件分发机制完全解析(1)
- Android:安卓Touch事件分发机制
- Android事件的分发传递机制
- 关于android事件分发(日记)