最大范围 外层蓝色区域是继承ViewGroup

中间红色区域,也是继承ViewGroup

最中间黑色区域,是继承View

布局相关的代码:

<!-- 事件分发 -->
<view.custom.heimacustomview.event_distribution.AnimalViewGroup
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"
android:background="@color/colorPrimary"> <view.custom.heimacustomview.event_distribution.DogViewGroup
android:id="@+id/dog_view_group"
android:layout_width="180dp"
android:layout_height="180dp"
android:background="@android:color/holo_red_light"> <view.custom.heimacustomview.event_distribution.DogFootView
android:layout_width="60dp"
android:layout_height="60dp"
/> </view.custom.heimacustomview.event_distribution.DogViewGroup> </view.custom.heimacustomview.event_distribution.AnimalViewGroup>

Activity:

/**
* 事件分发相关
*/
public static final String DISTRIBUTION_TAG = "distribution_tag"; @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean result = super.dispatchTouchEvent(ev);
Log.d(DISTRIBUTION_TAG, "Activity的dispatchTouchEvent() 返回结果:" + result);
return result;
} @Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
Log.d(DISTRIBUTION_TAG, "Activity的onTouchEvent() 返回结果:" + result);
return result;
}

最外层ViewGroup处理类:

public class AnimalViewGroup extends ViewGroup {

    private View dogViewGroupView;

    public AnimalViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
protected void onFinishInflate() {
super.onFinishInflate(); dogViewGroupView = getChildAt(0);
   } @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); dogViewGroupView.measure(dogViewGroupView.getLayoutParams().width, dogViewGroupView.getLayoutParams().height);
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) { Log.i(AnimalViewGroup.class.getSimpleName(),
"指定排版>>>>>>>> getMeasuredWidth():" + getMeasuredWidth() + " getMeasuredHeight:" + getMeasuredHeight());
dogViewGroupView.layout((getMeasuredWidth() / 2) - (dogViewGroupView.getWidth() / 2),
(getMeasuredHeight() / 2) - (dogViewGroupView.getLayoutParams().height / 2),
dogViewGroupView.getLayoutParams().width + ((getMeasuredWidth() / 2) - (dogViewGroupView.getWidth() / 2)),
dogViewGroupView.getLayoutParams().height + ((getMeasuredHeight() / 2) - (dogViewGroupView.getLayoutParams().height / 2)));
} /**
* 事件分发相关
*/ @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean result = super.dispatchTouchEvent(ev);
Log.d(DISTRIBUTION_TAG,
"AnimalViewGroup的dispatchTouchEvent() 返回值:" + result);
return result;
} @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean result = super.onInterceptTouchEvent(ev);
Log.d(DISTRIBUTION_TAG,
"AnimalViewGroup的onInterceptTouchEvent() 返回值:" + result);
return result;
} @Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
Log.d(DISTRIBUTION_TAG,
"AnimalViewGroup的onTouchEvent() 返回值:" + result);
return result;
}
}

中间层ViewGroup处理类:

public class DogViewGroup extends ViewGroup {

    private View dogFootView;

    public DogViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
protected void onFinishInflate() {
super.onFinishInflate(); // 拿到子类
dogFootView = getChildAt(0); } private int www;
private int hhh; @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); dogFootView.measure(dogFootView.getLayoutParams().width, dogFootView.getLayoutParams().height); www = MeasureSpec.getSize(widthMeasureSpec);
hhh = MeasureSpec.getSize(heightMeasureSpec); Log.i(DogViewGroup.class.getSimpleName(), "狗:www:" + www + " hhh:" + hhh);
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) { Log.i(DogViewGroup.class.getSimpleName(), "狗 getMeasuredWidth():" + getMeasuredWidth()); l = (www / 2) - (dogFootView.getLayoutParams().width / 2);
t = (hhh / 2) - (dogFootView.getLayoutParams().height / 2);
dogFootView.layout(l, t,
dogFootView.getLayoutParams().width + l,
dogFootView.getLayoutParams().height + t);
} /**
* 事件分发相关
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean result = super.dispatchTouchEvent(ev);
Log.d(DISTRIBUTION_TAG,
"DogViewGroup的dispatchTouchEvent() 返回值:" + result);
return result;
} @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean result = super.onInterceptTouchEvent(ev);
Log.d(DISTRIBUTION_TAG,
"DogViewGroup的onInterceptTouchEvent() 返回值:" + result);
return result;
} @Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
Log.d(DISTRIBUTION_TAG,
"DogViewGroup的onTouchEvent() 返回值:" + result);
return result;
}
}

最小区域的,View处理类:

public class DogFootView extends View {

    Paint paint = null;

    public DogFootView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setTextSize(30);
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
} private int www;
private int hhh; @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); Log.i(DogFootView.class.getSimpleName(), " getMeasuredWidth:" + getMeasuredWidth() + " getMeasuredHeight:" + getMeasuredHeight()); www = MeasureSpec.getSize(widthMeasureSpec);
hhh = MeasureSpec.getSize(heightMeasureSpec);
Log.i(DogFootView.class.getSimpleName(), "狗脚 按钮:www:" + www + " hhh:" + hhh);
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); canvas.drawColor(Color.BLACK); String str = "我是按钮"; Rect rect = new Rect(); paint.getTextBounds(str, 0, str.length(), rect); canvas.drawText(str, (www / 2) - (rect.width() / 2), (hhh / 2) - (rect.height() / 2) + rect.height(), paint); } /**
* 事件分发相关
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
boolean result = super.dispatchTouchEvent(event);
Log.d(HeimaTestActivity.DISTRIBUTION_TAG,
"DogFootView的dispatchTouchEvent() 返回值:" + result);
return result;
} @Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
Log.d(HeimaTestActivity.DISTRIBUTION_TAG,
"DogFootView的onTouchEvent() 返回值:" + result);
return result;
}
}
如果在传递过程中,某一环节是ture,会执行自己的onTouchEvent(),事件就会终止
如果在回传过程中,返回ture,事件消费掉,事件也会终止
下面这都是返回false情况下的流程:
    AnimalViewGroup的onInterceptTouchEvent() 返回值:false

        DogViewGroup的onInterceptTouchEvent() 返回值:false

            DogFootView的onTouchEvent() 返回值:false

            DogFootView的dispatchTouchEvent() 返回值:false

            开始回传

        DogViewGroup的onTouchEvent() 返回值:false

        DogViewGroup的dispatchTouchEvent() 返回值:false

    AnimalViewGroup的onTouchEvent() 返回值:false

    AnimalViewGroup的dispatchTouchEvent() 返回值:false

Activity的onTouchEvent() 返回结果:false

Activity的dispatchTouchEvent() 返回结果:false

Activity的onTouchEvent() 返回结果:false

Activity的dispatchTouchEvent() 返回结果:false

事件丢失

Android-自定义控件之事件分发的更多相关文章

  1. Android View 的事件分发原理解析

    作为一名 Android 开发者,每天接触最多的就是 View 了.Android View 虽然不是四大组件,但其并不比四大组件的地位低.而 View 的核心知识点事件分发机制则是不少刚入门同学的拦 ...

  2. Android中的事件分发机制

    Android中的事件分发机制 作者:丁明祥 邮箱:2780087178@qq.com 这篇文章这周之内尽量写完 参考资料: Android事件分发机制完全解析,带你从源码的角度彻底理解(上) And ...

  3. Android系统输入事件分发详解

    什么是输入事件? 我们知道,运行android系统的设备本质上是一台计算机,使用者在和计算机进行交互的时候可以抽象成简单的对计算机的输入和输出(IO).那么对于运行在计算机上的操作系统来说,操作系统在 ...

  4. 【转】Android中的事件分发和处理

    原文链接:http://www.apkbus.com/home.php?mod=space&uid=705730&do=blog&id=61207 上次跟大家分享了一下自定义V ...

  5. Android view 的事件分发机制

    1 事件的传递顺序是 Activity -> Window -> 顶层View touch 事件产生后,最先由 activity 的 dispatchTouchEvent 处理 /** * ...

  6. Android中的事件分发和处理

    上次跟大家分享了一下自定义View的一下要点,这次跟大家聊一下View的事件分发及处理,为什么主题都是View,因为作为一名初级应用层Android工程师,跟我打交道最多的莫过于各种各样的View,只 ...

  7. Android中的事件分发机制总结

    Android 的事件分发机制 一.View的事件分发总结: View的onTouchEvent和OnTouch区别  还是以自定义的TestButton为例. 我们可以通过重写onTouchEven ...

  8. 《Android View 的事件分发和滑动冲突》 —预习资料

    1. 阅读书籍<Android开发艺术探索>第三章 2. 提前阅读如下技术文章: http://blog.csdn.net/singwhatiwanna/article/details/3 ...

  9. Android View的事件分发

    如果接触android开发时间足够长的话,或多或少都会遇到各种各样事件冲突的问题,要想解决这类问题,对深入理解事件分发机制是很有必要的,接下来几天都会尽自己所能尽可能将这方面讲清楚.  View的事件 ...

  10. Android的Touch事件分发机制简单探析

    前言 Android中关于触摸事件的分发传递是一个很值得研究的东西.曾不见你引入了一个ListView的滑动功能,ListView就不听你手指的指唤来滚动了:也不知道为啥Button设置了onClic ...

随机推荐

  1. C语言的第一次实验报告

    一.实验题目,设计思路,实现方法 第四次 分支+循环 加强版 (4.2.7 装睡) 设计思路:由题意可知通过最初输入量判断循环次数,根据输出形式可知在每次循环中需重新定义输入量并判断其是否满足题中条件 ...

  2. Linux 开发环境搭建与使用——SlickEdit 的安装与配置

    SlickEdit 的介绍 vim 是公认很好用很完美,但是对新手来说,上手毕竟不是很容易.Windows 下程序员很多都很喜欢Source Insight 这个工具来看代码,各种语法高亮看着很舒服. ...

  3. zookeeper 运维

    尽管zookeeper在编程上有很多的阱陷,API也非常的难用,但zookeeper服务本身可以说是很牢靠的了,所以在网上貌似关于运维的文章比较少. 但省心并不代表不会出麻烦,下面总结下zookeep ...

  4. UE4 的json读写方式

    转自:http://blog.csdn.net/cartzhang/article/details/41009343 JSON 的解析有很多开源库.UE4的JSON使用在代码的Public->S ...

  5. 在 Ubuntu 16.04 LTS 上 离线安装 Docker / Docker-compose

    前情提要 今天上班后,突然接到现场的工程师的电话: XXX的现场环境组的的局域网,上不了互联网.bla bla bla..... 如果需要安装其他软件的话,只能是自己带过去安装... 听完现场工程师的 ...

  6. Spring中使用JDBC

    Spring中的数据库异常体系 使用JDBC(不使用Spring)的时候,我们需要强制捕获SQLException,否则无法使用JDBC处理任何事情.SQLException表示尝试访问数据库的时候出 ...

  7. [saiku] schema文件分析

    上一篇讲到了如何在管理台配置数据源 [ http://www.cnblogs.com/avivaye/p/4877767.html ] 这次来说明下shema文件里面是怎样配置Cube和角色权限的 通 ...

  8. 深入理解基于selenium的二次开发

    对于做web端自动化测试的人来说,可能接触selenium比QTP还要多,但是我们在做基于selenium的二次开发的时候,经常会说到二次开发是为了易于维护,很多人可能不懂得维护的价值是什么,和到底要 ...

  9. Jenkins是什么?

    Jenkins 是一个可扩展的持续集成引擎. 主要用于: l 持续.自动地构建/测试软件项目. l 监控一些定时执行的任务. Jenkins拥有的特性包括: l 易于安装-只要把jenkins.war ...

  10. 你真的了解lambda吗?一文让你明白lambda用法与源码分析

    本文作者: cmlanche 本文链接: http://www.cmlanche.com/2018/07/22/lambda用法与源码分析/ 转载来源:cmlanche.com 用法 示例:最普遍的一 ...