您的位置:首页 > 移动开发 > Android开发

android事件分发机制

2016-06-30 11:04 363 查看
View的事件分发机制举例

为按钮设置onClick点击事件和onTouch触摸事件的执行顺序为:

1、onClick事件:

button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TAG", "onClick execute");
}
});


2、onTouch事件:

button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("TAG", "onTouch execute, action " + event.getAction());
return false;
}
});


3、执行次序为:

onTouch是优先于onClick执行的,并且onTouch执行了两次,一次是按下ACTION_DOWN,一次是抬起ACTION_UP(你还可能会有多次移动ACTION_MOVE的执行,如果你手抖了一下)。因此事件传递的顺序是先经过onTouch,再传递到onClick。

4、onTouch方法是有返回值的,这里我们返回的是false,表示事件会继续传递;为true表示事件不继续传递了。(可以理解成事件被onTouch消费掉了)

只要你触摸到了任何一个控件,就一定会调用该控件的dispatchTouchEvent方法(该方法在View中)

dispatchTouchEvent源码为:

public boolean dispatchTouchEvent(MotionEvent event) {
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
return onTouchEvent(event);
}


1、如果条件为真,则执行onTouch(this, event)方法,否则执行的是onTouchEvent(event);

3、三个条件依次是:注册监听 + 控件处于enabled状态 + onTouch方法的返回值(也就是如果这个onTouch回调函数的返回值为true,则执行onTouch而不会执行 onTouchEvent(event),否则执行的是onTouchEvent(event),这就是为什么刚刚说“被消耗掉”了的原因)

3、onClick方法在onTouchEvent(event)方法中,当按钮状态为MotionEvent.ACTION_UP(即点击)时,会执行performClick()方法里回调被点击控件的onClick方方法

就是touch事件的层级传递。

1、我们都知道如果给一个控件注册了touch事件,每次点击它的时候都会触发一系列的ACTION_DOWN,ACTION_MOVE,ACTION_UP等事件。这里需要注意,如果你在执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了。简单的说,就是当dispatchTouchEvent在进行事件分发的时候,只有前一个action返回true,才会触发后一个action。

2、touch事件分发的机制总结为:

就拿按钮点击事件为例的touch事件分发的执行过程为:

①、当触摸到了任何一个控件,就一定会调用该控件的dispatchTouchEvent方法

②、dispatchTouchEvent方法中首先会执行onTouch这个回调函数,但是执行onTouch这个回调函数有两个前提条件、第一个提前提条件是该控件注册了触摸监听,第二个条件是该控件是的状态是Enable的。

③、onTouch回调函数会有一个返回值,返回这如果为true的话就代表本次触摸事件被消耗掉了,执行接触;返回值为false的话会继续执行onTouchEvent方法。

④、onTouchEvent方法就是真正执行点击事件的地方,也就是我们重写的onClick方法。

⑤、onTouchEvent方法中能够捕获一次点击事件当中ACTION_DOWN、ACTION_ MOVE、ACTION_UP这三个中作,当触摸动作为ACTION_UP会调用onClick方法。

ViewGroup的事件分发机制

ViewGroup的定义

Android中任何控件都是直接或者间接集成View的,ViewGroup也是一样,ViewGroup可以简单理解成一组View的集合,它里面既可以包含View,也可以包含ViewGroup,譬如说我们熟悉的LinearLayout、RelativeLayout布局就是ViewGroup的子类。

ViewGroup的事件分发举例

1、MyLayout继承LinaerLayout + 两个Button + 设置监听

myLayout.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("TAG", "myLayout on touch");
return false;
}
});
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TAG", "You clicked button1");
}
});
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TAG", "You clicked button2");
}
});


2、分别点击的结果为:

这里写图片描述

即当点击按钮的时候,MyLayout注册的onTouch方法并不会执行,只有点击空白区域的时候才会执行该方法。

可以先理解成Button的onClick方法将事件消费掉了,因此事件不会再继续向下传递。

3、ViewGroup中有一个onInterceptTouchEvent方法

public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}


如果重写这个方法,返回true的话执行结果为:

这里写图片描述

3. ViewGroup事件分发的流程

1、Android中touch事件的传递,绝对是先传递到ViewGroup,再传递到View的

2、当你点击了某个控件,首先会去调用该控件所在ViewGroup的dispatchTouchEvent方法,然后在布局的dispatchTouchEvent方法中找到被点击的相应控件,再去调用该控件的dispatchTouchEvent方法。

3、其中会有一个onInterceptTouchEvent方法对事件传递进行拦截,如果返回值为true的话就表示事件不往子View中传递,如果为false的话就表示不对事件传递进行拦截,事件会往子View中传递

Android事件分发机制大总结

Android中的控件都是直接或者间接继承View的,Viewgroup也是继承View的,ViewGroup中可以包含View,也可以包含ViewGroup,我们平时接触的譬如说LinearLayout啊、RelativeLayout就是ViewGroup的子类。

Android的事件分发机制我有看过它的源码,总的来说就是Android中触摸事件的传递都是先传递到ViewGroup,再传递到View的。我就举Button点击这个例子来讲解一下Android中触摸事件分发的大致流程吧。

当点击Button的时候,会调用这个控件所在布局的dispatchTouchEvent(),然后在这个布局中dispatchTouchEvent()方法中找到被点击控件的dispatchTouchEvent()方法。

在调用被点击控件的dispatchTouchEvent()方法之前会有一次触摸事件的拦截判断,如果触摸事件被拦截了,就不会再去执行被点击控件的dispatchTouchEvent函数了,也就不会再执行onClick点击事件了。而是执行ViewGroup控件中的dispatchTouchEvent()的onTouch触摸事件然后返回。

如果触摸事件没被拦截的话又是怎么做呢,就会ViewGroup中dispatchTouchEvent()方法中被点击控件的dispatchTouchEvent()方法,就不会执行ViewGroup中的onTouch方法了。

以上只是阐述了touch事件在ViewGroup中和View中的事件分发过程,但是具体得在一个View中的touch事件分发机制又是怎么样的呢,我们继续往下看

android里面当触摸到任何一个控件的时候就一定会调用这个控件的dispatchTouchEvent方法。dispatchTouchEvent方法中的源码首先会调用onTouch方法,不过这个方法要执行的话也需要有两个前提条件,一个是这个控件注册了触摸监听、第二个是这个控件的状态要是enabled的。

执行完onTouch方法之后,会有一个返回值,如果返回这为true的话代表这个点击事件不继续往下传递了,为false的话就表示点击事件继续往下传递,就会执行onTouchEvent方法,onClick方法就是在onTouchEvent中被调用的。

这样的话一个控件的触摸事件在ViewGroup以及View中的分发过程就完成了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: