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;
}
});
}
}

代码都很easy,基本都是信息打印,OK。那我们開始測试吧

假设轻轻点击自己定义Button,并手抖一下。会打印出什么信息呢?让我们来look一look

假设轻轻点击自己定义ImageView。并手抖一下,又会打印出什么信息呢?让我们来look一look

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

为什么会这样呢?

由于我在自己定义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就不会再得到运行了,也就是ACTION_MOVE,ACTION_UP事件将不会得到运行。

到了这里我建议先结合两位大神的源代码看看吧


看完以后再看看这张图,是不是瞬间明确了


实在想不明确的朋友能够把我上面的代码拷过去。依据自己的想法改一改,然后执行执行,非常快你就会豁然开朗


总结:当点击布局里的控件时。首先会调用ViewGroup的dispatchTouchEvent方法,假设onInterceptTouchEvent方法返回的是false,那么就会调用子View的dispatchTouchEvent方法(这种方法返回true就表示子View把事件消费掉了)。假设onInterceptTouchEvent方法返回的是true,那么就会调用ViewGroup的父类(也就是View)的dispatchTouchEvent方法,接下来调用布局的onTouch、onTouchEvent方法。

能够这么记着:布局把事情交给子View处理,子View的dispatchTouchEvent方法返回true表示它把事情干完了,布局就不处理了。假设返回false,就是子View没处理完,那么布局就要处理了。

(再回过头去看  ***切记那里,明确了么?朋友。假设一个事件你返回了false,后面的就是布局在处理了,所以子View后面的事件不会运行)

好吧。我承认这篇写的有点水,事实上主要是提供代码给大家执行着试试。自己动手。丰衣足食。



android菜鸟之路-事件分发机制总结(二)的更多相关文章

  1. Android 进阶学习:事件分发机制全然解析,带你从源代码的角度彻底理解(上)

    http://blog.csdn.net/guolin_blog/article/details/9097463 事实上我一直准备写一篇关于Android事件分发机制的文章,从我的第一篇博客開始,就零 ...

  2. 【Android - 进阶】之事件分发机制

    参考资料: View事件分发:http://blog.csdn.net/pi9nc/article/details/9281829 ViewGroup事件分发:http://blog.csdn.net ...

  3. Android与javascript中事件分发机制的简单比较

    在前面两篇博客中,我们讨论了Android中的事件分发的相关内容,那么在本篇博客当中,我们就简单探讨一下html或javascript中的事件分发机制,并进行简单的对比. 在前端中,对事件进行绑定有三 ...

  4. 拇指记者深入Android公司,打探事件分发机制背后的秘密

    前言 聊到事件分发,很多朋友就会想到view的dispatchTouchEvent,其实在此之前,Android还做了很多工作. 比如跨进程获取输入事件的方式?在dispatchTouchEvent责 ...

  5. Android中View的事件分发机制

    简介 事件也称MotionEvent,事件分发机制就是对MotionEvent事件的分发过程,即当一个MotionEvent发生之后,系统需要把这个事件传递给一个具体的View. 点击事件的分发过程由 ...

  6. Android开发之Touch事件分发机制

    原地址http://www.cnblogs.com/linjzong/p/4191891.html Touch事件分发中只有两个主角:ViewGroup和View.Activity的Touch事件事实 ...

  7. Android事件分发机制(二)30分钟弄明白Touch事件分发机制

    Touch事件分发中只有两个主角:ViewGroup和View.Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理. View在 ...

  8. Android中View的事件分发机制——Android开发艺术探索笔记

    原文链接 http://sparkyuan.me/ 转载请注明出处 介绍 点击事件的事件分发就是对MotionEvent事件的分发过程.当一个MotionEvent产生了以后,系统须要把这个事件传递给 ...

  9. Android事件分发机制(下)

    这篇文章继续讨论Android事件分发机制,首先我们来探讨一下,什么是ViewGroup?它和普通的View有什么区别? 顾名思义,ViewGroup就是一组View的集合,它包含很多的子View和子 ...

随机推荐

  1. 第3节 mapreduce高级:4、倒排索引的建立

    倒排索引建立 需求分析 需求:有大量的文本(文档.网页),需要建立搜索索引 最终实现的结果就是哪个单词在哪个文章当中出现了多少次 思路分析: 首选将文档的内容全部读取出来,加上文档的名字作为key,文 ...

  2. source collection list

    1.Anaconda:http://www.cnblogs.com/xiaoming123abc/p/6970890.html https://conda.io/docs/help-support.h ...

  3. Spring.Boot.1 -- 概览

    Spring Boot 是如何简化Java 开发的 SpringBoot的一些重要特征 长久以来,Spring 框架作为Java应用开发的框架地位稳固.最近在云计算.大数据.无结构数据持续化.函数式反 ...

  4. 获取本地验证码cookie

    window.document.onkeydown = function (evt) { evt = (evt) ? evt : window.event; if (evt.keyCode) { if ...

  5. Ztree节点前加上两个自定义按钮

    前言: 在我的权限管理模块遇到了给某些角色加权限的问题,这时就需要实现将每个模块做成树,在每个节点前加上预览和编辑的按钮,这样可以根据数据库的某个字段给每个角色赋权限. 必须必须吐槽的是,这部分的功能 ...

  6. CSS3 @font-face的url要添加?#iefix的原因

    转至:https://github.com/CSSLint/csslint/wiki/Bulletproof-font-face When using @font-face to declare mu ...

  7. Python中关于使用正则表达式相关的部分笔记

    一点点自己记的笔记,如果各位朋友看不懂,可以在评论区留言,会尽可能快的回复. 所有的知识点全部贴在代码上了,注释也写了. 建议大伙把代码拷到自己的机器上,运行,查看结果,然后,结合注释,再自己稍稍理解 ...

  8. HUAS Summer Contest#4 D题 DP

    Description Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了.要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的 ...

  9. Swagger UI教程

    文档源地址 http://www.68idc.cn/help/makewebs/qitaasks/20160621620667.html Swagger-UI本身只提供在线测试功能,要集成它还需要告诉 ...

  10. Xcode8、 iOS10 适配问题

    调用相机.相册.麦克风.位置等隐私问题崩溃解决办法 你的项目中访问了隐私数据,比如:相机,相册,联系人等,在Xcode8中打开编译的话,统统会crash,控制台会输出下面这样的日志: 这是因为iOS对 ...