首页 > 系统 > Android > 正文

android 事件分发机制

2019-11-09 17:35:31
字体:
来源:转载
供稿:网友

阅读目录

1.View的事件分发机制2.ViewGroup的事件分发机制回到顶部

1.View的事件分发机制

一个button,简单一点就是onTouch,还有onclick事件,我们一个一个来分析

首先响应的是dispatchTouchEvent

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

其实,在android源码的命名还是很有规律的,dispatchXXX,也就是分发机制,往往就是第一个需要响应的地方。

我们来分析下:touchlistener不为空,也就是view的使用者设置了回调。

第二个条件就是View必须是enable的。第三:onTouch返回false,就说明onTouch不消费该事件,由OnTouchEvent响应。

如果返回True,那么就会直接return。

所以onClick事件一定会被调到。

 onTouchEvent

最终会走到performClick这个方法。

复制代码
    public boolean performClick() {        final boolean result;        final ListenerInfo li = mListenerInfo;        if (li != null && li.mOnClickListener != null) {            playSoundEffect(SoundEffectConstants.CLICK);            li.mOnClickListener.onClick(this);            result = true;        } else {            result = false;        }        sendaccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);        return result;    }复制代码

可以看到,如果setOnClickListener, onClick 就会走到。

回到顶部

2.ViewGroup的事件分发机制

复制代码
<com.joyfulmath.frameworksample.viewdemo.MyLayout        android:id="@+id/my_layout"        android:background="#99000044"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <Button            android:id="@+id/button_id"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="button"/>        <Button            android:id="@+id/imageId"            android:layout_centerInParent="true"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@android:drawable/ic_lock_power_off"/>    </com.joyfulmath.frameworksample.viewdemo.MyLayout>复制代码

一个layout里面有2个button,

 TestViewAction

分别点击button1 & button2 & 灰色部分

等到log如下:

复制代码
08-27 10:19:26.799 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.880 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.896 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.913 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.926 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.926 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onClick: button_id [at (TestViewAction.java:38)]08-27 10:19:27.434 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: imageId [at (TestViewAction.java:58)]08-27 10:19:27.535 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: imageId [at (TestViewAction.java:58)]08-27 10:19:27.543 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: imageId [at (TestViewAction.java:58)]08-27 10:19:27.544 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onClick: imageId [at (TestViewAction.java:41)]08-27 10:19:28.111 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.156 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.173 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.190 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.237 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.237 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onClick: my_layout [at (TestViewAction.java:44)]复制代码

也就是点击button1以后,不会传递都layout

But,如果layout里面有一个函数

public boolean onInterceptTouchEvent(MotionEvent ev)

这个函数就是截断对button的分发处理,默认是return false。

至此,我们有了一个大概的流程。

Activtiy->ViewGroup->View 

如果仔细分析就会发现,在Activity里面有一个getDocView。所以Activity里面有个RootView的概念。

言归正传,ViewGroup本质上也是一个View,所以,可以把模型简单的定性为Activtiy->ViewGroup->View 三层。

首先Activity里面有2个函数,我们分析看看:

复制代码
    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        TraceLog.i();        return super.dispatchTouchEvent(ev);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        TraceLog.i();        return super.onTouchEvent(event);    }复制代码

所以大体流程如下:

1.@Activty.diapatchTouchEvent ->@Layout.dispatchTouchEvent->@layout.onInterceptTouchEvent return true/false

2.return true->@layout.onTouchEvent 后面部分同view

3.return false->@view.dispatchTouchEvent View的分发见上一片流程。

 

参考:

《深入理解android设计思想》   林学森

转载地址:http://www.cnblogs.com/deman/p/5812570.html


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表