android菜鸟之路-事件分发机制总结(二)
2016-01-07 09:23
543 查看
ViewGroup事件分发机制
自定义一个LinearLayout,ImageView和Button,小二,上代码<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <com.example.aaaaa.MyLinear android:id="@+id/linear" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#956456" > <com.example.aaaaa.MyImage android:id="@+id/id_ll" android:layout_width="150dp" android:layout_height="150dp" android:src="@drawable/ic_launcher" android:text="click me" /> <com.example.aaaaa.MyButton android:id="@+id/id_btn" android:layout_width="150dp" android:layout_height="150dp" android:src="@drawable/ic_launcher" android:text="click me" /> </com.example.aaaaa.MyLinear> </LinearLayout>
public class MyLinear extends LinearLayout{ private static final String TAG =MyLinear.class.getSimpleName(); public MyLinear(Context context, AttributeSet attrs) { super(context, attrs); } public MyLinear(Context context) { super(context); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "LinearLayout+onTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "LinearLayout+onTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "LinearLayout+onTouchEvent ACTION_UP"); break; default: break; } return super.onTouchEvent(event); } @Override public boolean dispatchTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "LinearLayout+dispatchTouchEvent ACTION_DOWN"); // return true; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "LinearLayout+dispatchTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "LinearLayout+dispatchTouchEvent ACTION_UP"); break; default: break; } boolean a=super.dispatchTouchEvent(event); // Log.e(TAG, "LinearLayout:a="+a); return a; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); } }
public class MyButton extends Button { private static final String TAG = MyButton.class.getSimpleName(); public MyButton(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "button+onTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "button+onTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "button+onTouchEvent ACTION_UP"); break; default: break; } return super.onTouchEvent(event); } @Override public boolean dispatchTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "button+dispatchTouchEvent ACTION_DOWN"); // return true; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "button+dispatchTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "button+dispatchTouchEvent ACTION_UP"); break; default: break; } boolean a=super.dispatchTouchEvent(event); // Log.e(TAG, "button:a="+a); return a; // return super.dispatchTouchEvent(event); } }
public class MyImage extends ImageView { private static final String TAG = MyImage.class.getSimpleName(); public MyImage(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "onTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "onTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "onTouchEvent ACTION_UP"); break; default: break; } return super.onTouchEvent(event); } @Override public boolean dispatchTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "dispatchTouchEvent ACTION_DOWN"); return false; // break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "dispatchTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "dispatchTouchEvent ACTION_UP"); break; default: break; } boolean a=super.dispatchTouchEvent(event); // Log.e(TAG, "ImageView:a="+a); return a; // return super.dispatchTouchEvent(event); } }
public class MainActivity extends Activity { protected static final String TAG = "MainActivity"; private MyImage imageView; private MyButton button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView=(MyImage) findViewById(R.id.id_ll); button=(MyButton) findViewById(R.id.id_btn); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.e(TAG, "setOnClickListener000"); } }); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.e(TAG, "button+setOnClickListener000"); } }); final LinearLayout ll = (LinearLayout) findViewById(R.id.linear); // ll.setOnClickListener(new OnClickListener() { // @Override // public void onClick(View v) { // Log.e(TAG, "LinearLayout+setOnClickListener000"); // } // }); // ll.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "LinearLayout+onTouch ACTION_DOWN"); Log.e(TAG, "LinearLayout+000"+ll.isClickable()); // return false; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "LinearLayout+onTouch ACTION_MOVE"); Log.e(TAG, "LinearLayout+000"+ll.isClickable()); // return false; break; case MotionEvent.ACTION_UP: Log.e(TAG, "LinearLayout+onTouch ACTION_UP"); Log.e(TAG, "LinearLayout+000"+ll.isClickable()); break; default: break; } return true; } }); imageView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "onTouch ACTION_DOWN"); Log.e(TAG, "000"+imageView.isClickable()); // return false; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "onTouch ACTION_MOVE"); Log.e(TAG, "000"+imageView.isClickable()); // return false; break; case MotionEvent.ACTION_UP: Log.e(TAG, "onTouch ACTION_UP"); Log.e(TAG, "000"+imageView.isClickable()); break; default: break; } return true; } }); button.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "button+onTouch ACTION_DOWN"); // Log.e(TAG, "button+000"+button.isClickable()); // return false; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "button+onTouch ACTION_MOVE"); // Log.e(TAG, "button+000"+button.isClickable()); // return false; break; case MotionEvent.ACTION_UP: Log.e(TAG, "button+onTouch ACTION_UP"); // Log.e(TAG, "button+000"+button.isClickable()); break; default: break; } return false; } }); } }代码都非常简单,基本都是打印信息,OK,那我们开始测试吧
如果轻轻点击自定义Button,并手抖一下,会打印出什么信息呢?让我们来look一look
如果轻轻点击自定义ImageView,并手抖一下,又会打印出什么信息呢?让我们来look一look
为什么会这样呢?
因为我在自定义ImageView的dispatchTouchEvent方法里的MotionEvent.ACTION_DOWN事件判断里返回了false,还记得我们上一篇结尾说的么?
***切记,只有每个ACTION_DOWN,ACTION_MOVE,ACTION_UP事件对应的dispatchTouchEvent方法都返回true,才能依次往后执行,就是说如果dispatchTouchEvent方法里此时的event.getAction()==ACTION_DOWN,
你返回了false,那么后面的dispatchTouchEvent方法都不会执行(说白了,每个动作事件都会执行一次dispatchTouchEvent,执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了,也就是[b]ACTION_MOVE,ACTION_UP事件将不会得到执行。[/b]
到了这里我建议先结合两位大神的源码看看吧
/article/1562149.html
/article/1336233.html
看完以后再看看这张图,是不是瞬间明白了
实在想不明白的朋友可以把我上面的代码拷过去,根据自己的想法改一改,然后运行运行,很快你就会豁然开朗
总结:当点击布局里的控件时,首先会调用ViewGroup的dispatchTouchEvent方法,如果onInterceptTouchEvent方法返回的是false,那么就会调用子View的dispatchTouchEvent方法(这个方法返回true就表示子View把事件消费掉了),如果onInterceptTouchEvent方法返回的是true,那么就会调用ViewGroup的父类(也就是View)的dispatchTouchEvent方法,接下来调用布局的onTouch、onTouchEvent方法。
可以这么记着:布局把事情交给子View处理,子View的dispatchTouchEvent方法返回true表示它把事情干完了,布局就不处理了;如果返回false,就是子View没处理完,那么布局就要处理了。(再回过头去看 ***切记那里,明白了么?朋友,如果一个事件你返回了false,后面的就是布局在处理了,所以子View后面的事件不会执行)
好吧,我承认这篇写的有点水,其实主要是提供代码给大家运行着试试,自己动手,丰衣足食。
相关文章推荐
- 慕课网的在线Android教学视频讲解(循序渐进)
- 【转】android错误 aapt.exe已停止工作的解决方法
- android学习日记(二):Fragment的详解下
- Android之Intent传递数据的方式
- Android编程实现读取本地SD卡图片的方法
- Android开发总结笔记 消息处理机制 5-1
- Android异步线程
- android学习9——Handler简单用法
- Android:反编译APK
- Android:SIM信息获取
- 史上最详细的Android Studio系列教程四--Gradle基础
- 你真的了解android getX getRawX view移动的原理吗????
- 史上最易懂的Android jni开发资料--NDK环境搭建
- AndroidStudio-/vendor/lib, /system/lib]]] couldn't find "libweibosdkcore.so"
- 第一次使用Android Studio时你应该知道的一切配置(3)
- Android 之 观察者模式
- 第一次使用Android Studio时你应该知道的一切配置(2)
- Android 补间动画解析(一)
- Android 之View绘图原理总结
- 第一次使用Android Studio时你应该知道的一切配置(1)