android 事件分发流程

今天整理下android的事件分发流程,在android中,所有控件都继承自View控件,以及View的子控件ViewGroup,今天说的事件分发机制就是以这两个控件来讲解:

在android的UI布局中,通常最低层都是继承自ViewGroup的容器类控件,最顶层的往往是继承自View的显示类控件,由于UI的需求,往往会出现多层容器嵌套的问题,在极端情况下,如果多层容器都需要处理滑动事件的话,就容易引起滑动事件冲突问题,在这里,我就详细分析下android中事件的传递过程,只要明白了事件传递过程,就可以在实际应用中处理好他们之间的冲突关系了。


滑动事件的传递过程在View以及ViewGroup中有些许不同,View中处理滑动事件跟两个方法有关,dispatchTouchEvent和onTouchEvent,ViewGroup是继承自View,除了上述两个方法外,还多了一个方法,就是onInterceptTouchEvent,下面是事件的传递过程:

View : dispatchTouchEvent -> onTouchEvent;

ViewGroup: dispatchTouchEvent -> onInterceptTouchEvent -> onTouchEvent;


为了清晰明了的分析事件传递过程,我们以实例来说话,下面先定义一个继承自ViewGroup的类,主要就是多了事件传递过程的打印信息,代码如下:

import android.content.Context;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup;

/**
 * @author: xiewenliang
 * @Filename:
 * @Description:
 * @date: 2017/4/14 14:18
 */

public class EventViewGroup extends ViewGroup {

    private String TAG;

    public EventViewGroup(Context context, String TAG) {
        super(context);
        this.TAG = TAG;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (getChildAt(0) != null) getChildAt(0).layout(l, t, r, b);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-dispatchTouchEvent");
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-onInterceptTouchEvent");
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-onTouchEvent");
        }
        return super.onTouchEvent(event);
    }
}

再来就是Activity的代码了,如下:

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.ViewGroup;

import com.example.viewpagertransformer.View.EventView;
import com.example.viewpagertransformer.View.EventViewGroup;

/**
 * @author: xiewenliang
 * @Filename:
 * @Description:
 * @date: 2017/4/14 14:17
 */

public class EventActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        EventViewGroup eventViewGroupA = new EventViewGroup(this, "A");
        EventViewGroup eventViewGroupB = new EventViewGroup(this, "B");
        EventViewGroup eventViewGroupC = new EventViewGroup(this, "C");
        eventViewGroupA.setLayoutParams(lp);
        eventViewGroupB.setLayoutParams(lp);
        eventViewGroupC.setLayoutParams(lp);
        eventViewGroupB.addView(eventViewGroupC);
        eventViewGroupA.addView(eventViewGroupB);
        setContentView(eventViewGroupA);
    }
}


Activity中我们的布局是三个容器嵌套在一起, 也就是A包涵B,B包涵C,A在容器的最低层,C在容器的最顶层,我们看一下打印的结果:

04-14 16:45:24.793 9105-9105/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 16:45:24.793 9105-9105/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 16:45:24.793 9105-9105/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent
04-14 16:45:24.793 9105-9105/com.example.viewpagertransformer I/MotionEvent: B-onInterceptTouchEvent
04-14 16:45:24.793 9105-9105/com.example.viewpagertransformer I/MotionEvent: C-dispatchTouchEvent
04-14 16:45:24.793 9105-9105/com.example.viewpagertransformer I/MotionEvent: C-onInterceptTouchEvent
04-14 16:45:24.793 9105-9105/com.example.viewpagertransformer I/MotionEvent: C-onTouchEvent
04-14 16:45:24.794 9105-9105/com.example.viewpagertransformer I/MotionEvent: B-onTouchEvent
04-14 16:45:24.794 9105-9105/com.example.viewpagertransformer I/MotionEvent: A-onTouchEvent


大家看到 事件的传递过程 就是从:A层dispatchTouchEvent -> A层onInterceptTouchEvent -> ~~ -> C层dispatchTouchEvent -> C层onInterceptTouchEvent ->

C层onTouchEvent -> ~ -> A层onTouchEvent。

从这里可以分析到 事件是从最底层的dispatchTouchEvent、onInterceptTouchEvent一直到最顶层的dispatchTouchEvent、onInterceptTouchEvent, 然后从最顶层的onTouchEvent回传到最底层的onTouchEvent。


明白了这些后,大家有看到,其实每个事件函数,都会返回一个布尔值,他们返回的布尔值是否会对事件传递产生影响呢? 下面我们通过事件来证明:

首先我们让A容器在dispatchTouchEvent方法中返回true,EventViewGroup的代码更改如下:

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-dispatchTouchEvent");
        }
        if ("A".equals(TAG)) return true;
        return super.dispatchTouchEvent(ev);
    }

也就是说 当事件传递到A的dispatchTouchEvent方法中,我们返回true,来看看事件传递打印结果:

04-14 16:56:36.706 16544-16544/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent


我们发现 事件只打印了一条,根据前面我们得到的事件传递顺序,可以得出,如果在dispatchTouchEvent中返回true,事件会在该容器的dispatchTouchEvent中直接消耗,不会传递到该容器的onInterceptTouchEvent方法,也不会继续向下传递,为了证实我们的猜测,我们把它改成在B容器中的dispatchTouchEvent方法中返回true,猜测结果应该是:A层dispatchTouchEvent -> A层onInterceptTouchEvent -> B层dispatchTouchEvent, 事件通过A的两个方法传递到B层就会结束,EventViewGroup代码修改如下:

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-dispatchTouchEvent");
        }
        if ("B".equals(TAG)) return true;
        return super.dispatchTouchEvent(ev);
    }

再来看看打印结果:

04-14 17:06:00.743 17930-17930/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:06:00.743 17930-17930/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:06:00.743 17930-17930/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent


结果也是证实了我们的猜测。得出的结论就是:如果在容器的dispatchTouchEvent中返回true,事件就会在该容器的dispatchTouchEvent方法中消耗,不会传递给该容器的其它事件处理方法,也不会继续向下传递事件。


接下来我们看看如果dispatchTouchEvent中返回false会是什么样的结果呢,EventViewGroup代码修改如下:

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-dispatchTouchEvent");
        }
        if ("A".equals(TAG)) return false;
        return super.dispatchTouchEvent(ev);
    }

这里我们更改A容器执行到dispatchTouchEvent方法直接返回false,看下事件打印结果:

04-14 17:12:09.040 23155-23155/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent


我们看到,打印结果跟返回true是一样的,难道这个方法返回false和true是一样的吗,带着这个猜测,我们继续在B容器中该方法返回false,EventViewGroup代码修改如下:

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-dispatchTouchEvent");
        }
        if ("B".equals(TAG)) return false;
        return super.dispatchTouchEvent(ev);
    }


打印结果:

04-14 17:15:30.366 26175-26175/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:15:30.366 26175-26175/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:15:30.366 26175-26175/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent
04-14 17:15:30.366 26175-26175/com.example.viewpagertransformer I/MotionEvent: A-onTouchEvent


我们看到,dispatchTouchEvent方法返回true和返回false还是不一样的,返回true的时候,直接事件直接就在该方法内结束了,不会再传递给其它事件处理方法和容器,如果返回false,则不会继续调用该容器的其它事件处理方法,但是事件会提前传递到上层容器的onTouchEvent事件处理方法中。好了,dispatchTouchEvent事件处理机制我们就实验到这里。


下面来实验一下onInterceptTouchEvent方法中的返回值对事件传递有什么影响呢,我们先修改容器A中该方法的返回值为true,EventViewGroup代码修改如下:

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-onInterceptTouchEvent");
        }
        if ("A".equals(TAG)) return true;
        return super.onInterceptTouchEvent(ev);
    }


打印结果:

04-14 17:24:35.009 1720-1720/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:24:35.010 1720-1720/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:24:35.010 1720-1720/com.example.viewpagertransformer I/MotionEvent: A-onTouchEvent


我们看到 事件在容器A中就结束了,按照正常流程,事件传递到A的onInterceptTouchEvent方法,接下来就是B的dispatchTouchEvent方法了,但是这里没有把事件传递到B的dispatchTouchEvent中,而是直接就传递到了A的onTouchEvent方法中,由此,我们猜测,如果在容器的onInterceptTouchEvent方法中返回true,该事件不会继续想子容器或者子控件传递,而是提现就交给了本容器的onTouchEvent方法处理,如果是这样,我们猜测,如果在B容器的onInterceptTouchEvent方法中返回true,事件的传递顺序应该是这样的 A层dispatchTouchEvent -> A层onInterceptTouchEvent -> B层dispatchTouchEvent -> B层onInterceptTouchEvent ->

B层onTouchEvent -> A层onTouchEvent,  而不会传递到C层,为了验证猜测,EventViewGroup代码修改如下:

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-onInterceptTouchEvent");
        }
        if ("B".equals(TAG)) return true;
        return super.onInterceptTouchEvent(ev);
    }

打印结果:

04-14 17:30:42.210 7308-7308/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:30:42.210 7308-7308/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:30:42.210 7308-7308/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent
04-14 17:30:42.210 7308-7308/com.example.viewpagertransformer I/MotionEvent: B-onInterceptTouchEvent
04-14 17:30:42.211 7308-7308/com.example.viewpagertransformer I/MotionEvent: B-onTouchEvent
04-14 17:30:42.211 7308-7308/com.example.viewpagertransformer I/MotionEvent: A-onTouchEvent


打印结果证明我们的猜测结果是正确的,所以总结如下:

当在容器的onInterceptTouchEvent方法中返回true,事件不会继续向子容器传递,而是提前传递给本容器的onTouchEvent方法。


下面我们来看看onInterceptTouchEvent方法中返回false,会是什么样的流程呢,我们先更改A容器的onInterceptTouchEvent方法返回false, EventViewGroup代码修改如下:

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-onInterceptTouchEvent");
        }
        if ("A".equals(TAG)) return false;
        return super.onInterceptTouchEvent(ev);
    }


打印结果:

04-14 17:34:15.351 10383-10383/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:34:15.351 10383-10383/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:34:15.351 10383-10383/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent
04-14 17:34:15.351 10383-10383/com.example.viewpagertransformer I/MotionEvent: B-onInterceptTouchEvent
04-14 17:34:15.351 10383-10383/com.example.viewpagertransformer I/MotionEvent: C-dispatchTouchEvent
04-14 17:34:15.351 10383-10383/com.example.viewpagertransformer I/MotionEvent: C-onInterceptTouchEvent
04-14 17:34:15.351 10383-10383/com.example.viewpagertransformer I/MotionEvent: C-onTouchEvent
04-14 17:34:15.351 10383-10383/com.example.viewpagertransformer I/MotionEvent: B-onTouchEvent
04-14 17:34:15.351 10383-10383/com.example.viewpagertransformer I/MotionEvent: A-onTouchEvent

我们发现,打印结果跟默认流程是一致的,是否onInterceptTouchEvent方法中默认返回值就是false呢,我们继续修改B中该方法返回值,EventViewGroup代码修改如下:

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-onInterceptTouchEvent");
        }
        if ("B".equals(TAG)) return false;
        return super.onInterceptTouchEvent(ev);
    }


打印结果:

04-14 17:36:11.767 12071-12071/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:36:11.767 12071-12071/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:36:11.767 12071-12071/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent
04-14 17:36:11.767 12071-12071/com.example.viewpagertransformer I/MotionEvent: B-onInterceptTouchEvent
04-14 17:36:11.767 12071-12071/com.example.viewpagertransformer I/MotionEvent: C-dispatchTouchEvent
04-14 17:36:11.767 12071-12071/com.example.viewpagertransformer I/MotionEvent: C-onInterceptTouchEvent
04-14 17:36:11.767 12071-12071/com.example.viewpagertransformer I/MotionEvent: C-onTouchEvent
04-14 17:36:11.767 12071-12071/com.example.viewpagertransformer I/MotionEvent: B-onTouchEvent
04-14 17:36:11.767 12071-12071/com.example.viewpagertransformer I/MotionEvent: A-onTouchEvent


打印结果证明我们的猜测是对的。如果容器的onInterceptTouchEvent方法中返回false,不会影响事件继续向下传递。


接下来我们分析最后一个方法,onTouchEvent,还是一样,先更改A容器中onTouchEvent返回true,EventViewGroup代码修改如下:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-onTouchEvent");
        }
        if ("A".equals(TAG)) return true;
        return super.onTouchEvent(event);
    }

打印结果:

04-14 17:38:53.838 14427-14427/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:38:53.838 14427-14427/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:38:53.838 14427-14427/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent
04-14 17:38:53.838 14427-14427/com.example.viewpagertransformer I/MotionEvent: B-onInterceptTouchEvent
04-14 17:38:53.839 14427-14427/com.example.viewpagertransformer I/MotionEvent: C-dispatchTouchEvent
04-14 17:38:53.839 14427-14427/com.example.viewpagertransformer I/MotionEvent: C-onInterceptTouchEvent
04-14 17:38:53.839 14427-14427/com.example.viewpagertransformer I/MotionEvent: C-onTouchEvent
04-14 17:38:53.839 14427-14427/com.example.viewpagertransformer I/MotionEvent: B-onTouchEvent
04-14 17:38:53.839 14427-14427/com.example.viewpagertransformer I/MotionEvent: A-onTouchEvent


我们看到打印流程跟正常流程一样,这是什么原因呢,我们看A容器的onTouchEvent本来就是事件传递的最后一个,所以看不出来影响,我们就更改B容器的onTouchEvent方法返回值为true,EventViewGroup代码修改如下:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-onTouchEvent");
        }
        if ("B".equals(TAG)) return true;
        return super.onTouchEvent(event);
    }
打印结果:

04-14 17:40:39.423 15966-15966/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:40:39.423 15966-15966/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:40:39.423 15966-15966/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent
04-14 17:40:39.423 15966-15966/com.example.viewpagertransformer I/MotionEvent: B-onInterceptTouchEvent
04-14 17:40:39.423 15966-15966/com.example.viewpagertransformer I/MotionEvent: C-dispatchTouchEvent
04-14 17:40:39.423 15966-15966/com.example.viewpagertransformer I/MotionEvent: C-onInterceptTouchEvent
04-14 17:40:39.423 15966-15966/com.example.viewpagertransformer I/MotionEvent: C-onTouchEvent
04-14 17:40:39.423 15966-15966/com.example.viewpagertransformer I/MotionEvent: B-onTouchEvent


我们看到 ,事件传递到B的onTouchEvent方法就结束了,我们猜测, 如果onTouchEvent返回true,事件就在onTouchEvent方法中消耗了,不会继续向上传递,为了验证猜测,我们继续修改C容器的onTouchEvent方法返回true, EventViewGroup代码修改如下:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.i("MotionEvent", TAG + "-onTouchEvent");
        }
        if ("C".equals(TAG)) return true;
        return super.onTouchEvent(event);
    }


打印结果:

04-14 17:43:26.432 18377-18377/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:43:26.432 18377-18377/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:43:26.432 18377-18377/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent
04-14 17:43:26.432 18377-18377/com.example.viewpagertransformer I/MotionEvent: B-onInterceptTouchEvent
04-14 17:43:26.432 18377-18377/com.example.viewpagertransformer I/MotionEvent: C-dispatchTouchEvent
04-14 17:43:26.432 18377-18377/com.example.viewpagertransformer I/MotionEvent: C-onInterceptTouchEvent
04-14 17:43:26.432 18377-18377/com.example.viewpagertransformer I/MotionEvent: C-onTouchEvent


打印结果证实了我们的猜测,如果容器onTouchEvent返回true,事件就在onTouchEvent方法中消耗了,不会继续向上传递。

为了节省验证时间,我们直接修改C容器的onTouchEvent返回false, 看看结果,EventViewGroup代码修改如下:

04-14 17:45:05.666 19822-19822/com.example.viewpagertransformer I/MotionEvent: A-dispatchTouchEvent
04-14 17:45:05.666 19822-19822/com.example.viewpagertransformer I/MotionEvent: A-onInterceptTouchEvent
04-14 17:45:05.667 19822-19822/com.example.viewpagertransformer I/MotionEvent: B-dispatchTouchEvent
04-14 17:45:05.667 19822-19822/com.example.viewpagertransformer I/MotionEvent: B-onInterceptTouchEvent
04-14 17:45:05.667 19822-19822/com.example.viewpagertransformer I/MotionEvent: C-dispatchTouchEvent
04-14 17:45:05.667 19822-19822/com.example.viewpagertransformer I/MotionEvent: C-onInterceptTouchEvent
04-14 17:45:05.667 19822-19822/com.example.viewpagertransformer I/MotionEvent: C-onTouchEvent
04-14 17:45:05.667 19822-19822/com.example.viewpagertransformer I/MotionEvent: B-onTouchEvent
04-14 17:45:05.667 19822-19822/com.example.viewpagertransformer I/MotionEvent: A-onTouchEvent

由打印结果,我们发现 onTouchEvent的返回值是false, 不会拦截事件,事件会继续向上层容器的onTouchEvent传递。

由上述实例,我们可以综合下得出事件传播流程图如下:


好了 现在我们再来看看View类和ViewGroup类有什么区别呢,我们看到,其实ViewGroup就是多了一个onInterceptTouchEvent函数,该函数的作用,就是在返回true的时候事件不再向下传递,而是传递给容器本身的onTouchEvent函数,如果是返回false,则是继续传递给下一个容器或者控件,分析一下,我们可以看出,View这类不作为容器的控件,是没有子控件的,所以它通过dispatchTouchEvent调用父类的dispatchTouchEvent方法,其实就直接调用了onTouchEvent方法,流程图可以稍作修改如下:

好了  android事件分发的流程就总结到这里。


在实际的应用中,其实我们还有一个更便捷的方法来控制事件的传播,那就是getParent().requestDisallowInterceptTouchEvent(true/false); 具体用法代码如下:

private float oldx, oldy;

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        // 通知该容器的所有上层容器,不要拦截或者消耗事件
        getParent().requestDisallowInterceptTouchEvent(true);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                float x = event.getX();
                float y = event.getY();
                if (Math.abs(x - oldx) > Math.abs(y - oldy)) {
                    // 当检测到是横向滑动事件时,通知该容器的所有上层容器,不要拦截或者消耗事件,事件由该容器本身处理
                    getParent().requestDisallowInterceptTouchEvent(true);
                } else {
                    // 当检测到是竖向滑动事件,通知该容器所有上层容器,该容器不再接收本次事件序列的剩余事件,由上层容器处理
                    getParent().requestDisallowInterceptTouchEvent(false);
                }
                oldx = x;
                oldy = y;
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
        }
        return super.dispatchTouchEvent(event);
    }

android事件分发流程就介绍到这里。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值