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. Mysql,Oracle使用rollup函数完成行列统计

    时间 2014-02-25 00:05:38  ITeye-博客 原文  http://53873039oycg.iteye.com/blog/2021445 主题 MySQLOracle数据库 昨天 ...

  2. C++ 之 string

    C++ 的 string 类封装了很多对字符串的常用操作. string 类是模板类 basic_string类,以 char作为其元素类型的类. string 以单字节作为一个字符,如果处理多字符集 ...

  3. PHP 反射API

    出处:http://blog.csdn.net/hguisu/article/details/7357421 PHP5添加了一项新的功能:Reflection.这个功能使得phper可以reverse ...

  4. 74-A/D指标,Accumulation/Distribution,积累/派发线,离散指标.(2015.7.1)

    A/D指标,Accumulation/Distribution 积累/派发线,离散指标 观井映天 2015.7.1

  5. python面向对象编程设计与开发

    一.什么是面向对象的程序设计 1.何为数据结构? 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合,如列表.字典. 2.何为编程? 编程是指程序员用特定的语法+数据结构+算法,组成的代码,告 ...

  6. 怎样判断有没有SQL注入?

    最为经典的单引号判断法: 在参数后面加上单引号,比如: http://xxx/abc.php?id=1' 如果页面返回错误,则存在 Sql 注入. 原因是无论字符型还是整型都会因为单引号个数不匹配而报 ...

  7. 7-10 公路村村通(30 分)(最小生成树Prim算法)

    7-10 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤1 ...

  8. 防火墙内设置FileZilla Server注意事项

    开启了Windows下的防火墙,如何设置FileZilla Server 相关选项,能在服务器端只开启21,23端口就可以正常连接使用 方法/步骤   1.       开启windows防火墙,同时 ...

  9. HDU 4479 权递增的最短路问题

    题目大意: 找一条节点 1 到节点 N 的最短路,保证这条路上每一条边都比前一条边长 dp[i] 表示在当前状态下1到i的最小值 先将所有边根据边的长度排一个序,再每次取出同一段相同长度的边去更新当前 ...

  10. Thinkphp5.0 的使用模型Model更新数据

    Thinkphp5.0 的使用模型Model更新数据 (1)使用update()方法进行更新数据 一.where条件写在更新数据中 (这种情况更新的数据,必须含主键) $res = User::upd ...