Android 事件分发机制:深入剖析从事件触发的整个流程 (android是什么)
请简述什么是android事件处理,并分析两种android事件处理机制的实现过程和区别
UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于监听器的事件处理。
对于基于监听器的事件处理而言,主要就是为Android界面组件绑定特定的事件监听器;对于基于回调的事件处理而言,主要做法是重写Android组件特定的回调函数,Android大部分界面组件都提供了事件响应的回调函数,我们主要重写它们就行。
一 基于监听器的事件处理
相比于基于回调的事件处理,这是更具“面向对象”性质的事件处理方式。在监听器模型中,主要涉及三类对象:
2)事件Event:事件封装了界面组件上发生的特定事件的具体信息,如果监听器需要获取界面组件上所发生事件的相关信息,一般通过事件Event对象来传递。
3)事件监听器Event Listener:负责监听事件源发生的事件,并对不同的事件做相应的处理。
基于监听器的事件处理机制是一种委派式Delegation的事件处理方式,事件源将整个事件委托给事件监听器,由监听器对事件进行响应处理。这种处理方式将事件源和事件监听器分离,有利于提供程序的可维护性。
举例:
View类中的OnLongClickListener监听器定义如下:(不需要传递事件)
[java] view plaincopyprint?
public interface OnLongClickListener {
boolean onLongClick(View v);
public interface OnLongClickListener {boolean onLongClick(View v);}
View类中的OnLongClickListener监听器定义如下:(需要传递事件MotionEvent)
[java] view plaincopyprint?
public interface OnTouchListener {
boolean onTouch(View v, MotionEvent event);
public interface OnTouchListener {boolean onTouch(View v, MotionEvent event);}
二 基于回调的事件处理
相比基于监听器的事件处理模型,基于回调的事件处理模型要简单些,该模型中,事件源和事件监听器是合一的,也就是说没有独立的事件监听器存在。当用户在GUI组件上触发某事件时,由该组件自身特定的函数负责处理该事件。通常通过重写Override组件类的事件处理函数实现事件的处理。
举例:
View类实现了接口中的一系列回调函数,因此,基于回调的事件处理机制通过自定义View来实现,自定义View时重写这些事件处理方法即可。
[java] view plaincopyprint?
public interface Callback {
// 几乎所有基于回调的事件处理函数都会返回一个boolean类型值,该返回值用于
// 标识该处理函数是否能完全处理该事件
// 返回true,表明该函数已完全处理该事件,该事件不会传播出去
// 返回false,表明该函数未完全处理该事件,该事件会传播出去
boolean onKeyDown(int keyCode, KeyEvent event);
boolean onKeyLongPress(int keyCode, KeyEvent event);
boolean onKeyUp(int keyCode, KeyEvent event);
boolean onKeyMultiple(int keyCode, int count, KeyEvent event);
public interface Callback { // 几乎所有基于回调的事件处理函数都会返回一个boolean类型值,该返回值用于 // 标识该处理函数是否能完全处理该事件// 返回true,表明该函数已完全处理该事件,该事件不会传播出去// 返回false,表明该函数未完全处理该事件,该事件会传播出去boolean onKeyDown(int keyCode, KeyEvent event);boolean onKeyLongPress(int keyCode, KeyEvent event);boolean onKeyUp(int keyCode, KeyEvent event);boolean onKeyMultiple(int keyCode, int count, KeyEvent event);}
三 比对
基于监听器的事件模型符合单一职责原则,事件源和事件监听器分开实现;
Android的事件处理机制保证基于监听器的事件处理会优先于基于回调的事件处理被触发;
某些特定情况下,基于回调的事件处理机制会更好的提高程序的内聚性。
四 基于自定义监听器的事件处理流程
在实际项目开发中,我们经常需要自定义监听器来实现自定义业务流程的处理,而且一般都不是基于GUI界面作为事件源的。这里以常见的app自动更新为例进行说明,在自动更新过程中,会存在两个状态:下载中和下载完成,而我们的程序需要在这两个状态做不同的事情,“下载中”需要在UI界面上实时显示软件包下载的进度,“下载完成”后,取消进度条的显示。这里进行一个模拟,重点在说明自定义监听器的事件处理流程。
4.1)定义事件监听器如下:
Android 经典笔记之四: 事件冲突解决思路与方案
事件冲突解决思路与方案 目录介绍 1.事件机制简单介绍 1.1 触摸事件 1.2 分发事件 1.3 拦截事件
2.解决滑动冲突的思路及方法 2.1 第一种情况,滑动方向不同 2.2 第二种情况,滑动方法相同 2.3 第三种情况,以上两种情况嵌套
3.案例解决方法 3.1 针对2问题的解决思路 3.2 滑动方向不同,解决冲突的外部解决法 3.3 滑动方向不同,解决冲突的内部解决法 3.4 ViewPager嵌套ViewPager内部解决法 3.5 滑动方向相同,解决冲突的外部解决法 3.6 解决ScrollView和ViewPager,RecycleView滑动冲突
1.事件机制简单介绍 1.1 触摸事件
1.2 分发事件
1.3拦截事件
2.解决滑动冲突的思路及方法 2.1 第一种情况,滑动方向不同
看了上面三种情况,我们知道他们的共同特点是 父View 和 子View 都想争着响应我们的触摸事件,但遗憾的是我们的触摸事件 同一时刻 只能被某一个View或者ViewGroup拦截消费,所以就产生了滑动冲突?那既然同一时刻只能由某一个View或者ViewGroup消费拦截,那我们就只需要 决定在某个时刻由这个View或者ViewGroup拦截事件,另外的 某个时刻由 另外一个View或者ViewGroup拦截事件不就OK了吗?综上,正如 在 《Android开发艺术》 一书提出的,总共 有两种解决方案
3.2 滑动方向不同,解决冲突的外部解决法【 以ScrollView与ViewPager为例 】
3.3 滑动方向不同,解决冲突的内部解决法【 以ScrollView与ViewPager为例 】
3.4 ViewPager嵌套ViewPager内部解决法
3.5 滑动方向相同,解决冲突的外部解决法【解决ScrollView和RecycleView滑动冲突】
后续: 平时喜欢写写文章,笔记。别人建议我把笔记,以前写的东西整理,然后写成博客,所以我会陆续整理文章,只发自己写的东西,敬请期待: 知乎:领英::csdn:网易博客:新浪博客:github:喜马拉雅听书:脉脉:yc 开源中国:邮箱:
Android TV 按键焦点事件分发流程详解
DecorView →PhoneWindow →Activity→ViewGroup→view
下面我们根据按键事件的分发流程,抽丝剥茧,逐一分析。
private int processKeyEvent(QueuedInputEvent q)
通过该方法,接收器receiver的onKeyDown、onKeyUp、onKeyLongPress、onKeyMultiple等方法将被回调。
在上述按键事件的入口中提到的ViewRootImpl中
如果(event)返回true,则结束事件分发; 如果返回false,则调用如下方法
继续执行后续的焦点导航流程。 焦点导航的总体流程就是: 1、View focused = ();//从视图树的顶层,即DecorView一层一层的递归查找当前获得焦点的view 2、View v = (direction);根据导航的方向查找下一个可获取焦点的view 3、(direction, mTempRect)请求获取焦点 4、(direction,mTempRect)内部,调用(this, focused)逐层递归向上级通知
mView即DecorView,从DecorView开始,一层一层的向下递归查找当前获得焦点的view
找到了当前获得焦点的focused,调用该焦点view的focusSearch(direction)方法查找direction方向上下一个将要获取焦点的view。 (direction)实际上会调用(this, direction)方法,层层递归,直到调用到DecorView的focusSearch(this, direction)方法。 而DecorView继承ViewGroup,实际上最终会调用到()(this, focused, direction),this 就是DecorView对象。
最终会调用到DecorView父类ViewGroup中的()(this, focused, direction);
搜索到下一个获取焦点的view后,调用该(direction, mTempRect)方法 注意:调用requestFocus(direction, mTempRect)需要区分调用者。 如果是ViewGroup,则会更加焦点获取策略,实现父View和子View之间获取焦点的优先级。 如下是 和 中requestFocus方法是实现:
View获取到焦点后,会调用(this, focused)逐层递归向上级通知
若对本页面资源感兴趣,请点击下方或右方图片,注册登录后
搜索本页相关的【资源名】【软件名】【功能词】或有关的关键词,即可找到您想要的资源
如有其他疑问,请咨询右下角【在线客服】,谢谢支持!
相关文章
- 让您的内容焕发活力:体验我们无与伦比的动态海报生成器,点亮您的社交媒体形象 (让您的内容焕发出来)
- 释放您的想象力:用我们先进的动态海报生成器打造引人注目的视觉效果 (释放您的想象英文)
- 从人群中脱颖而出:用我们创新的动态海报生成器为您的广告增加活力 (从人群中脱颖而出英文)
- 拥抱视觉动态:探索我们革命性的动态海报生成器,让您的内容栩栩如生 (拥抱视觉动态表情包)
- 解锁无限创意:利用我们的直观动态海报生成器为您的品牌赋能 (无限创意屋)
- 提升您的视觉传播:发现我们前沿的动态海报生成器如何改变游戏规则 (提升您的视觉能力)
- 告别静态内容!用我们的革命性的动态海报生成器让您的内容脱颖而出 (告别静态内容怎么写)
- 释放您的营销潜力:体验我们的颠覆性的动态海报生成器 (释放您的营销潜力)
- 用我们的动态海报生成器瞬间提升您的社交媒体影响力 (用我们的动态描写句子)
- 小说封面设计变轻松,一键生成个性化封面提升作品竞争力 (小说封面设计教程)
发表评论
评论列表
- 这篇文章还没有收到评论,赶紧来抢沙发吧~