Android事件拦截机制简单分析

前一阶段,在学习的时候,遇到了我认为的我接触安卓以来的最多的一次事件拦截出来,那个项目,用到了slidemenu侧滑菜单栏,然后加上tab标签,还有轮播广告,listview上下滑动,viewpager的左右监听,如果没有处理各种事件的监听,那么就会一团糟,会让系统不知道到底要响应你的哪一个事件,有了点启发,在这自己就写一个小的demo来分享一下事件的拦截机制。
我们想要了解事件拦截机制,我们首先来看下onInterceptTouchEvent这个方法:

onInterceptTouchEvent:

  • 负责对touch事件拦截,对于嵌套的view,最先执行的是所点击view的onInterceptTouchEvent,然后依次执行子视图中的onInterceptTouchEvent(这里没有做任何处理,假设所有嵌套视图的onInterceptTouchEvent都会得到执行,也就是默认的返回false)就是有事情了,总监先去处理,然后经理处理,然后员工处理。(父视图先处理事情),事件拦截成功的标志就是onInterceptTouchEvent的返回值,如果返回fasle,没有拦截成功,返回true,拦截成功。
  • Android事件拦截机制简单分析_第1张图片

首先来看下我的文件布局:(最上面是一个自定义的view,中间的和下面的是两个自定义的viewgroup)
布局很简单:中间的和下面的那个是继承的RelativeLayout,最上面的继承的textview。

package com.example.touchintercept;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.RelativeLayout;

/** * Created by 若兰 on 2016/2/14. * 一个懂得了编程乐趣的小白,希望自己 * 能够在这个道路上走的很远,也希望自己学习到的 * 知识可以帮助更多的人,分享就是学习的一种乐趣 * QQ:1069584784 * csdn:http://blog.csdn.net/wuyinlei */

public class DirectorView extends RelativeLayout {

    private static String TAG = "wuyinlei";
    public DirectorView(Context context) {
        super(context);
    }

    public DirectorView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DirectorView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d(TAG, "DirectorView onInterceptTouchEvent");
        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.d(TAG, "DirectorView dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, "DirectorView onTouchEvent");
        return super.onTouchEvent(event);
    }

}

其他的两个也是一样的,里面没有实现任何的逻辑。

Android事件拦截机制简单分析_第2张图片
我们首先来看下,什么处理都没有做的(只是简单的写了onInterceptTouchEvent和onTouchEvent)
这个时候我们来点击textview,看看打印的log:
Android事件拦截机制简单分析_第3张图片

可以看见,正常的状况事件的传递顺序是:

  • 总监(DirectorView)–>经理(ManagerView)—>我(MyView)
  • 事件传递的时候,先执行dispatchTouchEvent方法然后执行onInterecptTouchEvent方法

事件处理的顺序是:

  • 我(MyView)–>经理(ManagerView)—>总监(DirectorView)
  • 这个就很好理解了,比如说卖房的时候,如果买房的要的优惠在员工(我)的能力范围之内,那么我返回ture,把事件处理了,也就是拦截,如果超出了我的优惠范围,我就返回false,不拦截,继续到经理,一层一层的处理。
  • 初始情况都是返回false (dispatchTouchEvent方法我们一般不住处理的)
    我们来看下整个事件过程的图形说明:

总监处理事件

下面我们改动一下,假如一个买房的顾客和总监很熟,那么他直接去找了总监,那么总监直接把优惠给了这个顾客,也就是事件没必要往下传递了,这个时候我们只需要修改DirectorView中的onInterecptTouchEvent方法返回true,我们看下log:

这个时候我们看下图形解释的拦截事件:
Android事件拦截机制简单分析_第4张图片

经理处理事件

在来看下一个场景,这个中产阶级的员工,去买房,他只认识经理,那么他直接去找经理谈能给的优惠,并且两个人是好朋友,这个时候就会把他能给的最大优惠给这个买房的,这个时候我们调整ManagerView中的onInterecptTouchEvent方法返回true,我们看下log:
Android事件拦截机制简单分析_第5张图片
这个时候我们看下图形解释的拦截事件:
Android事件拦截机制简单分析_第6张图片

员工(我)处理事件

这个时候,想必对于事件的分发、拦截大家应该比较清楚了,这个时候我们再来看下底层的MyView.记得我们刚开始的时候,顺其自然,我们返回的是false,就是一级一级的往上报告,不过这个时候,过来了一个买房的,有钱,但是不认识经理和总监,当然了哈,他也不在乎钱,这个时候你就给了他自己能给的优惠,双方达成一致,有钱人买了一套房,你也不用向上级反映,这个时候我们返回true:
Android事件拦截机制简单分析_第7张图片
这个时候他们之间的关系图如下所示:

还有就是,如果经理在onTouchEvent中返回了true,那么事件传递到经理这里也就不传递了,就好比,员工做错了事情,经理一看,不想把自己员工丢人的事情让总监看,那么他就返回true:
Android事件拦截机制简单分析_第8张图片
这个时候他们之间的关系图如下所示:
Android事件拦截机制简单分析_第9张图片
相信通过这几步的分析,还是比较容易的了解事件的分发、拦截、处理机制的,如果想要进一步的了解,大家可以去结合一下源码,然后在自己写一个demo演示,相信会有更深层的体会。

你可能感兴趣的:(android)