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. 纯CSS3来自定义单选框radio与复选框checkbox

    单选框(radio)自定义样式 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 3 ...

  2. java线程学习1

    java实现多线程有三种方式:继承Thread类,重写run方法,启动使用start:实现runnable接口,重写run方法:实现callable接口,重写call方法(可以有返回值,也可以抛出异常 ...

  3. 【软件构造】(转)Java中的comparable和comparator

    为了方便阅读和复习,转载至此,原地址:温布利往事的博客 阅读目录 一.Comparable简介 二.Comparator简介 三.Comparable和Comparator区别比较 回到顶部 一.Co ...

  4. 模板—trie图

    做了某题之后发现trie的AC自动机太垃圾了,动不动就TLE,然后我就去学了trie图. #include<iostream> #include<cstdio> using n ...

  5. 计算机中的CPU

    今天写一下计算机中最核心的一部分,就是计算机的大脑---CPU.CPU也就是中央处理器(Central Processing Unit).中央处理器是一块超大规模的集成电路,是一台计算机的运算核心(C ...

  6. KBE——查询

    关于def文件的flags(这个标签表明了属性的作用域) 没有只在client的作用域

  7. 怎样提高DB2存储过程性能

    高性能的SQL过程是数据库开发人员所追求的,我将不断把学到的,或在实际开发中用到的一些提高SQL过程性能的技巧整理出来,温故而知新. 1,在只使用一条语句即可做到时避免使用多条语句 让我们从一个简单的 ...

  8. 【BZOJ 1202】 [HNOI2005]狡猾的商人 (加权并查集)

    题链:http://www.lydsy.com/JudgeOnline/problem.php?id=1202 Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪 ...

  9. Leetcode 137.只出现一次的数字II

    只出现一次的数字II 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? ...

  10. MYSQL Sorting result 把队列堆满了,该怎么办?

    show processlist;发现有200多个队列,select cardnum from table where xxxid = 31 order by abc_time desc 这样的一个排 ...