最大范围 外层蓝色区域是继承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. TreeSet函数

    TreeSet类的排序问题   TreeSet支持两种排序方法:自然排序和定制排序.TreeSet默认采用自然排序. 1.自然排序 TreeSet会调用集合元素的compareTo(Object ob ...

  2. Solr-DIH建立索引并执行简单初步的查询

    我们将solr的安装目录设置为$SOLR_INSTALL,   ./solr start,不使用任何原有的examples来进行,启动完成后,不存在任何的core,提示No cores availab ...

  3. probably another instance of uWSGI is running on the same address

    probably another instance of uWSGI is running on the same address 可以用命令杀掉这个端口在重启: /tcp

  4. OpenCV Hello World

    ▶ OpenCV 的环境配置与第一个程序 ● 去官网下载安装包 https://opencv.org/releases.html ▶ OpenCL 在Visual Studio 2015 中的配置.注 ...

  5. Linux及安卓的事件处理资料

    事件处理机制介绍: https://source.android.com/devices/input/overview.html http://newandroidbook.com/Book/Inpu ...

  6. python的多线程编程之锁

    1. 背景概述 在上篇文章中,主要讲述了python中的socket编程的一些基本方面,但是缺少关于锁的相关概念,从而在这篇文章中进行补充. 由于在python中,存在了GIL,也就是全局解释器锁,从 ...

  7. jQuery用FormData对象实现文件上传以及如何通过ajax下载文件

    之前在Vue的项目里面用到过文件上传,封装好的组件用起来比较顺手,查询Element-UI文档,十八般武器样样都有,一顿操作猛如虎,一看--跑偏了(⊙o⊙)-,我的意思就是用框架实现比较简单,但是如果 ...

  8. How to Integrate JCaptcha in Spring Security

    The repository for JCaptcha is this one: <repository> <id>sourceforge-releases</id> ...

  9. zookeeper简绍

    先一句话概括下zookeeper:zookeeper可谓是目前使用最广泛的分布式组件了.其功能和职责单一,但却非常重要. zookeeper到底是什么?(技术文) 1)zookeeper实际上是yah ...

  10. 问题记录,StartCoroutine(“str")问题

    StartCoroutine参数为函数字符串名,运行时出错,错误是:无法启动协程函数. 调用格式如下: gameManager.StartCoroutine(LuaOnLevelwasloaded() ...