Android事件分发机制

部署运行你感兴趣的模型镜像

本篇仅作为自学笔记,以及学习分享,内容来源于:

https://blog.youkuaiyun.com/qq_30379689/article/details/53967177#commentBox

关于Android事件分发机制,面试回答总结就是以下几点:

  • dispatchTouchEvent 
    • return true:表示该View内部消化掉了所有事件
    • return false:表示事件在本层不再继续进行分发,并交由上层控件的onTouchEvent方法进行消费
    • return super.dispatchTouchEvent(ev):默认事件将分发给本层的事件拦截onInterceptTouchEvent方法进行处理
  • onInterceptTouchEvent 
    • return true:表示将事件进行拦截,并将拦截到的事件交由本层控件的onTouchEvent进行处理
    • return false:表示不对事件进行拦截,事件得以成功分发到子View
    • return super.onInterceptTouchEvent(ev):默认表示不拦截该事件,并将事件传递给下一层View的dispatchTouchEvent
  • onTouchEvent 
    • return true:表示onTouchEvent处理完事件后消费了此次事件
    • return fasle:表示不响应事件,那么该事件将会不断向上层View的onTouchEvent方法传递,直到某个View的onTouchEvent方法返回true
    • return super.dispatchTouchEvent(ev):表示不响应事件,结果与return false一样

自定义MyView 

/**
 * Created by zzf on 2018/8/29.
 */

public class MyView extends View {
    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        LogUtils.d("MyView------->onTouchEvent");

        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        LogUtils.d("MyView------->dispatchTouchEvent");
        return super.dispatchTouchEvent(event);
    }
}

自定义MyViewGroup01 

/**
 * Created by zzf on 2018/8/29.
 */

public class MyViewGroup01 extends LinearLayout {
    public MyViewGroup01(Context context) {
        super(context);
    }

    public MyViewGroup01(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyViewGroup01(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        LogUtils.d("MyViewGroup01------->dispatchTouchEvent");

        return super.dispatchTouchEvent(ev);
//        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        LogUtils.d("MyViewGroup01------->onInterceptTouchEvent");

        return super.onInterceptTouchEvent(ev);
//        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        LogUtils.d("MyViewGroup01------->onTouchEvent");

//        return super.onTouchEvent(event);
        return false;
    }
}

 自定义MyViewGroup02

/**
 * Created by zzf on 2018/8/29.
 */

public class MyViewGroup02 extends LinearLayout {
    public MyViewGroup02(Context context) {
        super(context);
    }

    public MyViewGroup02(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyViewGroup02(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        LogUtils.d("MyViewGroup02------->dispatchTouchEvent");

        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        LogUtils.d("MyViewGroup02------->onInterceptTouchEvent");

        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        LogUtils.d("MyViewGroup02------->onTouchEvent");

        return super.onTouchEvent(event);
    }
}

xml布局文件 

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <com.haiyungroup.oceansonic.customview.MyViewGroup02
        android:background="#ff0000"
        android:layout_width="300dp"
        android:layout_height="500dp">

        <com.haiyungroup.oceansonic.customview.MyViewGroup01
            android:background="#00ff00"
            android:layout_width="200dp"
            android:layout_height="400dp">

            <com.haiyungroup.oceansonic.customview.MyView
                android:background="#0000ff"
                android:layout_width="@dimen/dimen_150dp"
                android:layout_height="300dp" />
        </com.haiyungroup.oceansonic.customview.MyViewGroup01>
    </com.haiyungroup.oceansonic.customview.MyViewGroup02>


</FrameLayout>

分析事件传递

点击MyView(即蓝色部分):先接收事件的是父容器(MyViewGroup02)往下分发,而事件的分发过程中分为两步骤

  • 分发过程
  • 处理过程

其正常的分发事件结果为

//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
MyView dispatchTouchEvent
//处理过程
MyView onTouchEvent
MyViewGroup01 onTouchEvent
MyViewGroup02 onTouchEvent

1、dispatchTouchEvent(分发事件)

如果在MyViewGroup01的dispatchTouchEvent方法中返回true,表示需要在MyViewGroup01消费了整个事件,即不会再分发,也不会再处理。dispatchTouchEvent方法中返回true的打印信息

//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent

如果在MyViewGroup01的dispatchTouchEvent方法中返回false,表示在MyViewGroup01点击事件在本层不再继续进行分发,并交由上层控件的onTouchEvent方法进行消费。dispatchTouchEvent方法中返回false的打印信息

//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
//处理过程
MyViewGroup02 onTouchEvent

2、onInterceptTouchEvent(拦截事件)

如果在MyViewGroup01的onInterceptTouchEvent方法中返回true,表示需要在MyViewGroup01拦截这个点击事件,不再继续往下分发,即MyView不再执行dispatchTouchEvent方法。但是只是分发结束了而已,接着开始处理事件。下面是onInterceptTouchEvent方法中返回true的打印信息

//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
//处理过程
MyViewGroup01 onTouchEvent
MyViewGroup02 onTouchEvent

如果在MyViewGroup01的onInterceptTouchEvent方法中返回false,表示需要在MyViewGroup01不会拦截这个点击事件,继续往下分发。下面是onInterceptTouchEvent方法中返回false的打印信息

//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
MyView dispatchTouchEvent
//处理过程
MyView onTouchEvent
MyViewGroup01 onTouchEvent
MyViewGroup02 onTouchEvent

3、onTouchEvent(消费事件)

如果MyViewGroup01的onTouchEvent方法中返回true,表示MyViewGroup01可以将该事件直接消费掉了,即分发结束后,处理事件的时候,直接处理到MyViewGroup01就可以结束了。下面是onTouchEvent方法中返回true的打印信息

//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
MyView dispatchTouchEvent
//处理过程
MyView onTouchEvent
MyViewGroup01 onTouchEvent

如果MyViewGroup01的onTouchEvent方法中返回false,表示MyViewGroup01不可以将该事件直接消费掉,即事件继续往上处理。下面是onTouchEvent方法中返回false的打印信息

//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
MyView dispatchTouchEvent
//处理过程
MyView onTouchEvent
MyViewGroup01 onTouchEvent
MyViewGroup02 onTouchEvent

您可能感兴趣的与本文相关的镜像

Kotaemon

Kotaemon

AI应用

Kotaemon 是由Cinnamon 开发的开源项目,是一个RAG UI页面,主要面向DocQA的终端用户和构建自己RAG pipeline

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值