Android事件分发简单介绍

简单的讨论下关于Android的事件分发,其实网上的介绍很多,但是每次看完我都记的很晕,而我也只想知道当不同的返回值事件走的流程,所以这也只为自己做个简单的记录
首先说一下关于事件分发ViewGroup和View对应的方法
ViewGroup:dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent、
View:dispatchTouchEvent、onTouchEvent
再定义了两个类GroupTest继承于LinearLayout(ViewGroup)和ButtonTest继承于Buttom(View),界面布局:

    <com.mmf.ibinderdemo.GroupTest
        android:id="@+id/lyt_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <com.mmf.ibinderdemo.ButtonTest
            android:id="@+id/btn_test"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:text="click"/>
    </com.mmf.ibinderdemo.GroupTest>

一、事件拦截

onInterceptTouchEvent(MotionEvent ev)方法
从上面可以看出这个方法只有ViewGroup有,作用是拦截事件向下传递,啥意思呢,就是当你的ViewGroup中有子控件,而在onInterceptTouchEvent被拦截了,那么你的子控价就收不到touch事件,我们从代码中来看这个效果
在GroupTest复写事件分发的三个方法

  @Override
    public boolean onInterceptTouchEvent(MotionEvent ev){
        super.onInterceptTouchEvent(ev);
        Log.e("Touch = ", "group onInterceptTouchEvent  "+ ev.getAction() );
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("Touch = ", "group onTouchEvent  "+ event.getAction() );
        return  super.onTouchEvent(event);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean dispatchTouch = super.dispatchTouchEvent(ev);
        Log.e("Touch = ", "group dispatchTouchEvent +   " +dispatchTouch +ev.getAction());
        return dispatchTouch;
    }

ButtonTest复写

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("Touch = ", "chile touch");
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.e("Touch = ", "chile dispatchTouchEvent");
        return super.dispatchTouchEvent(event);
    }

当onInterceptTouchEvent返回true时查看运行结果

10-20 05:17:13.207 8138-8138/com.mmf.ibinderdemo E/Touch =: group onInterceptTouchEvent  0
10-20 05:17:13.208 8138-8138/com.mmf.ibinderdemo E/Touch =: group onTouchEvent  0
10-20 05:17:13.208 8138-8138/com.mmf.ibinderdemo E/Touch =: group dispatchTouchEvent +   true0
10-20 05:17:13.302 8138-8138/com.mmf.ibinderdemo E/Touch =: group onTouchEvent  1
10-20 05:17:13.302 8138-8138/com.mmf.ibinderdemo E/Touch =: group dispatchTouchEvent +   true1
10-20 05:17:13.303 8138-8138/com.mmf.ibinderdemo E/MainActivity: lyt_test: grouptrue

当onInterceptTouchEvent返回false时查看运行结果

10-20 05:28:46.053 8362-8362/com.mmf.ibinderdemo E/Touch =: group onInterceptTouchEvent  0
10-20 05:28:46.053 8362-8362/com.mmf.ibinderdemo E/Touch =: chile dispatchTouchEvent
10-20 05:28:46.053 8362-8362/com.mmf.ibinderdemo E/Touch =: chile onTouchEvent
10-20 05:28:46.053 8362-8362/com.mmf.ibinderdemo E/Touch =: group dispatchTouchEvent +   true0
10-20 05:28:46.183 8362-8362/com.mmf.ibinderdemo E/Touch =: group onInterceptTouchEvent  1
10-20 05:28:46.183 8362-8362/com.mmf.ibinderdemo E/Touch =: chile dispatchTouchEvent
10-20 05:28:46.183 8362-8362/com.mmf.ibinderdemo E/Touch =: chile onTouchEvent
10-20 05:28:46.183 8362-8362/com.mmf.ibinderdemo E/Touch =: group dispatchTouchEvent +   true1
10-20 05:28:46.185 8362-8362/com.mmf.ibinderdemo E/MainActivity: btn_test: chiletrue

从以上结果可以看出当onInterceptTouchEvent返回true时会拦截事件的分发,子view接收不到事件,不执行onTouchEvent事件
如果返回 false,则表示不会拦截该事件,事件会被传递到子 View 上,执行onTouchEvent事件

二、事件消费

onTouchEvent(MotionEvent ev)这个方法就是用来处理具体点击事件的,它是在dispatchTouchEvent方法中调用
它的返回值表示是否消费当前事件,也就是是否响应当前事件,具体逻辑如下:
如果return true 则会接收并消费该事件。
如果return false,那么这个事件会向上传递,并由上层 View 的 onTouchEvent 来接收,如果传递到上面的 onTouchEvent 还是返回 false,这个事件无效,且接收不到下一次事件。什么意思呢,我们来看一下运行效果,将ButtonTest的onTouchEvent方法设置返回false,其他的保持原本状态

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        Log.e("Touch = ", "chile onTouchEvent = " + event.getAction());
        return false;
    }

执行结果

10-20 07:29:57.526 10182-10182/com.mmf.ibinderdemo E/Touch =: group onInterceptTouchEvent  0
10-20 07:29:57.526 10182-10182/com.mmf.ibinderdemo E/Touch =: chile dispatchTouchEvent
10-20 07:29:57.526 10182-10182/com.mmf.ibinderdemo E/Touch =: chile onTouchEvent = 0
10-20 07:29:57.526 10182-10182/com.mmf.ibinderdemo E/Touch =: group onTouchEvent  0
10-20 07:29:57.526 10182-10182/com.mmf.ibinderdemo E/Touch =: group dispatchTouchEvent +   true0
10-20 07:29:57.643 10182-10182/com.mmf.ibinderdemo E/Touch =: group onTouchEvent  1
10-20 07:29:57.643 10182-10182/com.mmf.ibinderdemo E/Touch =: group dispatchTouchEvent +   true1
10-20 07:29:57.643 10182-10182/com.mmf.ibinderdemo E/MainActivity: lyt_test: grouptrue

将ButtonTest的onTouchEvent方法设置返回true,其他的保持原本状态

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        Log.e("Touch = ", "chile onTouchEvent = " + event.getAction());
        return true;
    }

执行结果

10-20 07:28:25.021 10118-10118/? E/libprocessgroup: failed to make and chown /acct/uid_10066: Read-only file system
10-20 07:28:34.403 10118-10118/com.mmf.ibinderdemo E/Touch =: group onInterceptTouchEvent  0
10-20 07:28:34.403 10118-10118/com.mmf.ibinderdemo E/Touch =: chile dispatchTouchEvent
10-20 07:28:34.403 10118-10118/com.mmf.ibinderdemo E/Touch =: chile onTouchEvent = 0
10-20 07:28:34.403 10118-10118/com.mmf.ibinderdemo E/Touch =: group dispatchTouchEvent +   true0
10-20 07:28:34.530 10118-10118/com.mmf.ibinderdemo E/Touch =: group onInterceptTouchEvent  1
10-20 07:28:34.530 10118-10118/com.mmf.ibinderdemo E/Touch =: chile dispatchTouchEvent
10-20 07:28:34.530 10118-10118/com.mmf.ibinderdemo E/Touch =: chile onTouchEvent = 1
10-20 07:28:34.530 10118-10118/com.mmf.ibinderdemo E/Touch =: group dispatchTouchEvent +   true1
10-20 07:28:34.531 10118-10118/com.mmf.ibinderdemo E/MainActivity: btn_test: chiletrue

从结果上看,当返回false时,ButtonTest的onTouchEvent方式只执行了一次down的事件,别的事件都不再执行,且GroupTest消费了事件
当返回true时,表示该事件被这个ButtonTest消费了,GroupTest都没听调过onTouchEvent方法,因为事件被消费不再向上传递
ps:事件对应的值

MotionEvent.ACTION_DOWN = 0
MotionEvent.ACTION_MOVE = 2
MotionEvent.ACTION_UP = 1

三、事件分发

dispatchTouchEvent(MotionEvent ev)
竟然最后一个说事件分发,顺序跟事件步骤相反,因为我觉得如果事件拦截和事件消费大概流程懂了,事件分发就会更好理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值