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. 07CSS表格

    CSS表格 表格边框 如需在 CSS 中设置表格边框,请使用 border 属性. table, th, td { border: 1px solid blue; } 折叠边框 border-coll ...

  2. B4. Concurrent JVM 锁机制(synchronized)

    [概述] JVM 通过 synchronized 关键字提供锁,用于在线程同步中保证线程安全. [synchronized 实现原理] synchronized 可以用于代码块或者方法中,产生同步代码 ...

  3. IIS+php服务器无法上传图片解决办法

    查找网上资料,发现php.ini下面有2个地方关于上传的配置: file_uploads = On  这里设置是否允许HTTP上传,默认应该为ON的 ;upload_tmp_dir=  这里设置上传文 ...

  4. python 弹窗

    import ctypes message = ctypes.windll.user32.MessageBoxA(0,'message','tips',0)

  5. Windows系列原版系统镜像下载

    原版系统镜像下载 Windows 10 系统 Windows 10 企业版 1511版 (64位) Windows 10 Enterprise, Version 1511 (x64) – DVD (C ...

  6. Python基础 - pip导出依赖环境和安装依赖环境的命令

    导出:    pip freeze > requirements.txt 安装:    pip install -r requirements.txt

  7. LeetCode(60) Permutation Sequence

    题目 The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of th ...

  8. Atcoder regular Contest 073(C - Sentou)

    Atcoder regular Contest 073(C - Sentou) 传送门 每个人对开关的影响区间为a[i]--a[i]+t,因此此题即为将所有区间离散化后求所有独立区间的长度和 #inc ...

  9. spring+orm框架的兼容问题

    Springframework和Hibernate版本对应关系 org.springframework 3.0.x对应org.hibernate4.0.x版本 org.springframework ...

  10. 添物不花钱学JavaEE(基础篇) --HTML

    HTML是什么? HTML – Hyper Text Markup Language HTML官方网址 http://www.w3.org/TR/2014/REC-html5-20141028/ 其实 ...