上一篇《Android自己定义组件系列【5】——进阶实践(2)》继续对任老师的《可下拉的PinnedHeaderExpandableListView的实现》进行了分析,这一篇计划中间插一段“知识点”,对Android中的事件分发机制进行解析。

细心的朋友可能会发现。打开大牛写的Android项目,里面非常多组件都是自己定义的(这就是为什么界面和体验这么吸引你的原因)。可是要灵活的去自己定义组件就必须对手势(也就是各种监听)必须熟悉,能处理好事件之间的关系。

先看一段代码:

    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {Log.i(TAG, "onClick");}});button.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:Log.i(TAG, "onTouch  down");break;case MotionEvent.ACTION_MOVE:Log.i(TAG, "onTouch move");break;case MotionEvent.ACTION_UP:Log.i(TAG, "onTouch up");break;default:break;}return false;}});}

能够看到onTouch方法会被先调用,然后才调用onClick方法。假设我们将上面onTouch方法的返回值改为true,则onClick方法不会被调用。事件将被onTouch方法消费。

还记得前几篇文章中都会使用一个dispatchTouchEvent的方法吗.

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

能够看到在dispatchTouchEvent中调用了onTouch方法,所以会先于onClick方法调用。

假设onTouch返回true后dispatcheTouchEvent就会直接返回true则不会再运行其它方法。

在Android系统中每一个ViewGroup子类都具有例如以下三个方法:

public boolean dispatchTouchEvent(MotionEvent event)  :用来分发TouchEvent

public boolean onInterceptTouchEvent(MotionEvent event) :用来拦截TouchEvent

public boolean onTouchEvent(MotionEvent event) :处理TouchEvent

<?xml version="1.0" encoding="utf-8"?

> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <com.kris.touch.widget.TouchView android:id="@+id/view_out" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#fff" android:gravity="center"> <com.kris.touch.widget.TouchView android:id="@+id/view_mid" android:layout_width="300px" android:layout_height="400px" android:background="#f00" android:gravity="center"> <com.kris.touch.widget.TouchView android:id="@+id/view_center" android:layout_width="150px" android:layout_height="150px" android:background="#000" android:gravity="center" android:clickable="true"> </com.kris.touch.widget.TouchView> </com.kris.touch.widget.TouchView> </com.kris.touch.widget.TouchView> </LinearLayout>

首先触摸事件(ACTION_DOWN)发生后。系统调用Activity的dispatchTouchEvent方法,分发事件。依据触摸事件的坐标,将此事件传递给out(最外层)的dispatchTouchEvent处理。out则调用onInterceptTouchEvent方法推断事件是否由自己来处理。还是向下传递给子View.假设out不处理该事件会依据事件产生坐标分发给它的直接子View.

图中center组件是可点击的(clickable)组件。表示能处理Touch事件,所以center中的onInterceptTouchEvent方法将事件传递给center

TouchEvent中。假设返回值是true,则说明消耗(消费)了这个事件,不会再向下传递。假设返回值是false,则没有消耗事件,会继续传递下去。假设center中不会处理事件(android:clickable="false"),事件不会被center的onTouchEvent消费,则事件会层层逆向回到activity。

关于事件分发机制就先了解到这里,下一篇接着分析......

Android自己定义组件系列【6】——进阶实践(3)相关推荐

  1. Android自己定义组件系列【4】——自己定义ViewGroup实现双側滑动

    在上一篇文章<Android自己定义组件系列[3]--自己定义ViewGroup实现側滑>中实现了仿Facebook和人人网的側滑效果,这一篇我们将接着上一篇来实现双面滑动的效果. 1.布 ...

  2. Android自己定义组件系列【2】——Scroller类

    在上一篇中介绍了View类的scrollTo和scrollBy两个方法,对这两个方法不太了解的朋友能够先看<自己定义View及ViewGroup> scrollTo和scrollBy尽管实 ...

  3. Android自己定义DataTimePicker(日期选择器)

    Android自己定义DataTimePicker(日期选择器)  笔者有一段时间没有发表关于Android的文章了,关于Android自己定义组件笔者有好几篇想跟大家分享的,后期会记录在博客中.本篇 ...

  4. Android深入四大组件(六)Android8.0 根Activity启动过程(前篇)

    相关文章 Android深入四大组件系列 Android系统启动系列 Android应用程序进程系列 Android深入解析AMS系列 前言 在几个月前我写了Android深入四大组件(一)应用程序启 ...

  5. Android深入四大组件(七)Android8.0 根Activity启动过程(后篇)

    相关文章 Android深入四大组件系列 Android系统启动系列 Android应用程序进程系列 Android深入解析AMS系列 前言 在几个月前我写了Android深入四大组件(一)应用程序启 ...

  6. Android组件之BroadCast简单实践

    作为Android的四大组件之一,没有理由不介绍一下BroadCast,BroadCast中文简单翻译就是广播,前阵子浙江某大学的啦啦操,广场舞的大妈,其中大妈和学生从喇叭和音响上听到的声音就是事件源 ...

  7. XCoreRedux框架:Android UI组件化与Redux实践

    XCoreRedux框架:Android UI组件化与Redux实践 @author: 莫川 https://github.com/nuptboyzhb/ XCoreRedux源码+Demo:http ...

  8. Android基础知识巩固系列 Android之四大组件——ContentProvider(内容提供者)

    因为最近要面试,于是打算整理整理一下Android的基础知识,由于之前本人已经学习过大概的Android基础知识,这里主要讲这四大组件.五大存储.六大布局.网络请求等这些内容,其他一些等有时间再整理, ...

  9. Android 自己定义View (二) 进阶

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125 继续自己定义View之旅.前面已经介绍过一个自己定义View的基础 ...

最新文章

  1. 测试集没有标签,应该怎么办?
  2. 《PHP开发入行真功夫》
  3. Autograd:自动求导
  4. android 接口定义常量,Android开发笔记(5):常量的合理使用
  5. Python3 中你知道有多少错误和异常
  6. Docker镜像源更改
  7. css 样式文字溢出显示省略号
  8. 分享一款国外的优化IE9浏览器的软件感觉很好用兼容win7
  9. 浅谈Java新手入门书籍选择
  10. 如何复制出计算机缓存中的歌曲,怎么把哔哩哔哩里缓存的视频中的音频单独提取出来。...
  11. Nature拟推出机器智能在线期刊Nature Machine Intelligence
  12. 天津博物馆镇馆之宝——西周太保鼎
  13. [WSL]Ubuntu指定的网络名不可再用
  14. 为什么要求高频pcb板低ε(Dk)
  15. 从项目的一个 panic 说起:Go 中 Sync 包的分析应用
  16. GitHub 又一黑科技项目面世!网友惊呼:这也太强了
  17. 创建一个8*8的国际象棋棋盘(黑块为0,白块为1)
  18. 信息系统项目管理师 第一章-信息系统与信息化
  19. 资产计提折旧日志查询(AFBP)和数据反查(FB03 / AW01N)
  20. 软件设计模式学习(十四)外观模式

热门文章

  1. Nuxt.js开发中碰到的问题(二)引入gitment评论系统
  2. FastDFS蛋疼的集群和负载均衡(十五)之lvs四层+Nginx七层负载均衡
  3. Static Text控件响应函数方法
  4. CentOS7 64位下 MySQL5.7的安装与配置(YUM)
  5. mac下Android studio配置gradle的路径
  6. ABAP中使用浏览器打开网页
  7. 转 DevExpress-ASPxPageControl 动态添加 TabPage 内容
  8. Spring源码窥探之:xxxAware接口
  9. 设计模式03------单例模式
  10. BZOJ4563[Haoi2016]放棋子