Android开发小知识5—事件分发机制详细解析

事件概论

在Android开发中,事件的处理是非常重要的一部分,Android程序的事件流程参考了Java中的事件处理操作。 如要进行事件处理,必须要有一个事件源。事件源的产生可以有很多形式,如单击按钮、长按等,之后根据此事件源找到相应的事件处理操作类对事件进行处理。这篇文章中将详细的分析Android事件。

事件处理流程图.png

上图中事件处理主要涉及3个对象:

  • Event Source(事件源):事件发生的场所,可以简单的理解为组件。
  • Event(事件):事件封装了界面组件上发生的特定事件,通常是用户的操作,比如点击事件。可以通过Event获取具体事件。
  • Event Listener(事件监听器):监听事件源所发生的事件,并做出相应的处理。

事件监听器

事件监听器是View类中包含一个回调方法的接口。 当用户与APP发生交互,触发已注册此视图的监听器时,Android 将调用这些方法。

View.OnClickListener:当用户点击组件时, 调用此方法。

View.OnLongClickListener: 当用户长按组件时,将调用此方法。此方法必须返回一个布尔值,返回 true 表示您已经处理事件且事件应就此停止;如果您尚未处理事件和或事件应该继续传递给其他任何点击监听器,则返回 false。

View.OnFocusChangeListener: 当组件的焦点改变时,将调用此方法。

View.OnKeyListener:当APP的键盘发生状态改变时,将调用此方法。此方法必须返回一个布尔值,表示您是否已处理完事件,以及是否应该将它继续传下去。 也就是说,返回 true 表示您已经处理事件且事件应就此停止;如果您尚未处理事件和或事件应该继续传递给其他任何按键监听器,则返回 false。

View.OnTouchListener: 当用户执行可视为触摸事件的操作时,其中包括按下、释放或屏幕上的任何移动手势,将调用此方法。在复杂的布局中,此方法的调用永远一定的先后顺序(在后面将详细提及)。

View.OnCreateContextMenuListener: 当需要生成菜单时,将调用此方法。

这些方法是其相应接口的唯一成员。要定义其中一个方法并处理事件,一般的做法是在 Activity 中实现嵌套接口或将其定义为匿名类。然后,将实现的实例传递给相应的View.set...Listener()方法.例如,调用setOnClickListener()并向其传递OnClickListener实现。

匿名类实现
button.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  //TODO someting
              }
          });

事件处理程序(Event)

默认事件处理程序的回调方法中,有如下几种用于事件处理的常见回调,其中包括:

  • onKeyDown(int, KeyEvent):在发生新的按键事件时调用。
  • onKeyUp(int, KeyEvent):在发生按键弹起事件时调用。
  • onTrackballEvent(MotionEvent):在发生轨迹球运动事件时调用。
  • onTouchEvent(MotionEvent):在发生触摸屏运动事件时调用。
  • onFocusChanged(boolean, int, Rect):在视图获得或失去焦点时调用。
事件的类型:

ACTION_DOWN:表示用户开始触摸。
ACTION_MOVE:表示用户在移动(手指或者其他)。
ACTION_UP:表示用户抬起了手指。
ACTION_CANCEL:表示手势被取消了。
ACTION_OUTSIDE:表示用户触碰超出了正常的UI边界。
ACTION_POINTER_DOWN:有一个非主要的手指按下了。
ACTION_POINTER_UP:一个非主要的手指抬起来了。

事件发生的位置,x,y轴:

getX():获得事件发生时,触摸的中间区域在屏幕的X轴。
getY() :获得事件发生时,触摸的中间区域在屏幕的X轴。
在多点触控中还可以通过:
getX(int pointerIndex):来获得对应手指事件的发生位置. 获得X轴用。
getY(int pointerIndex):来获得对应手指事件的发生位置. 获得Y轴用 。

事件分发机制

在管理布局内更复杂的事件时,对于事件的响应处理会从最顶层的组件不断向子组件传递,一直到最后的View组件。因此,在复杂布局中,对事件的处理也要考虑一下如下方法。

onTouchEvent:在发生触摸屏运动事件时调用。是真正用来进行业务逻辑处理的地方,返回true表示已经将该事件消费,返回false表明事件继续传递。

onInterceptTouchEvent:此方法允许ViewGroup监视分派给子视图的事件,返回false表示无需拦截,则递归的调用子组件的dispatchTouchEvent。返回true表示需要拦截,则直接调用本组件的onTouchEvent方法进行处理。因此,次方法只会存在于ViewGroup中。

dispatchTouchEvent:此方法的情况比较复杂,要区分在ViewGroup和View中的其区别。
ViewGroupdispatchTouchEvent()具体的执行逻辑:

首先执行本组件的onInterceptTouchEvent。如果返回false,表明无需拦截,则调用第二个方法,即子组件的dispatchTouchEvent方法;如果返回true,无需向子组件传递,则直接调用本组件的onTouchEvent方法。 如果需要向子组件传递事件。如果递归调用子组件的dispatchTouchEvent返回false,则调用本组件的onTouchEvent方法;如果递归调用子组件的dispatchTouchEvent返回true,则无需调用本组件的onTouchEvent方法。 最后子组件的dispatchTouchEvent的返回值会返回给父组件的dispatchTouchEvent方法。

view中的dispatchTouchEvent会直接调用其自身的onTouchEvent

ViewGroup`dispatchTouchEvent()`.png

总结

对于事件,重要的是在设计开发中的应用和理解。这里只是分享了我的一些认识。如有不足之处,希望多多指出。文章参考了AndroidAPI指南Android MotionEvent事件响应机制

原文作者litterMay
原文链接:http://www.jianshu.com/p/8e8e048fa61e

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容