Android中的事件处理总结
Android系统对动作做出的响应机制就是事件处理。Android提供了两种事件处理机制。
- 基于监听的事件处理机制
- 基于回调的事件处理机制
一、基于监听的事件处理机制
Android的事件监听机制就是一种”面向对象”的事件处理,是一种”委派模式(Delegate)”事件处理方式。Android的UI组件(事件源)将整个事件处理委托给特定的对象(事件***);当该事件源发生指定的事件时,就通知所委托的事件***,由事件***来处理事件。例如:消防所(事件***)监听所有的火灾事件并处理火灾,所有的企事业单位(事件源)当发生火灾时本身自己无法灭火,都委托给消防所来灭火。
所以基于监听的事件的处理模型中,主要涉及三类对象:
- Event Source(事件源):事件发生的Android组件。例如:按钮、菜单等
- Event(事件): UI上面的事件源发生的特定的事件,一般都是通过Event对象获取。例如:长按、点击等
- Event Listener(事件***):负责监听事件源所发生的的事件,对各种事件做出相应的反应。例如:处理登录业务的响应。
事件监听模式分为以下几种使用场景:
- 内部类形式:将事件***类定义成当前类的内部类
- 外部类形式:将事件***类定义成一个外部类
- Activity本身作为事件***类:让Activity本身实现***接口,并实现事件处理方法
- 匿名内部类形式:使用匿名内部类创建***对象
- 直接绑定标签:直接在界面布局文件中指定标签绑定事件处理函数
方法一:内部类形式
将***类定义成当前类的内部类
方法二:外部类
将事件***类定义为一个外部类,通过外部类对事件源进行监听,并在外部类实现事件。
方法三: Activity本身作为事件***类
1.***设置为this,代表自身类、
2.自身类实现事件监听接口View.OnClickListener、
3.自身类重写接口onClick方法
方法四:匿名内部类
使用匿名内部类创建***对象
方法五:直接绑定标签
通过UI布局文件,设定UI控件的android:onClick的属性(事件处理方法),在相应的Activity代码文件中里面设置跟android:onClick设置的同名方法,且该方法必须是public void的,同时有一个View类型的参数
基于监听的事件处理机制总结:
1).通过设置UI组件的android:onClick属性,然后代码实现方法:此方法业务逻辑和UI耦合性太高,实际业务一般不用
2).匿名类:一般只应用特定组件的特定业务响应
3).内部类:当前类可以重复使用该***类;当前类的所有界面组件都可以使用该内部类作为***。
4).外部类:可作为多个UI共同的事件处理,适用多个UI组件复用;但事件源要传递信息给事件***时则不太灵活,必须通过成员变量及构造方法
5).Activity自身类:处理比较灵活,实际中用的最多
6).当同一个UI对同一个事件注册多个***时,根据注册的顺序,最后注册的事件***优先触发,事件不再传递,最后触发的是通过UI设定的方法
二、基于回调的事件处理机制
监听机制是一种委托(Delegate)的事件处理方式;而回调机制则是事件源和事件监听是统一的(自己的事情自己干)。
方法回调是将功能定义与功能分开的一种手段,一种解耦合的设计思想;在Java中回调是通过接口来实现的, 作为一种系统架构,必须要有自己的运行环境,且需要为用户提供实现接口;实现依赖于客户,这样就可以 达到接口统一,实现不同,系统通过在不同的状态下"回调"我们的实现类,从而达到接口和实现的分离!
Android提供的GUI组件上发生的所有事情,系统都提供了对应的事件处理方法,Java是一种静态语言无法给GUI组件或对象提供动态的添加方法,只能继承GUI,通过重写该类的处理方法来实现回调事件处理。 Android为GUI组件提供大量响应事件的方法,可以用于回调的使用。
常见View组件的回调方法:
android为GUI组件提供了一些事件处理的回调方法,以View为例,有以下几个方法
①在该组件上触发屏幕事件: boolean onTouchEvent(MotionEvent event);
②在该组件上按下某个按钮时: boolean onKeyDown(int keyCode,KeyEvent event);
③松开组件上的某个按钮时: boolean onKeyUp(int keyCode,KeyEvent event);
④长按组件某个按钮时: boolean onKeyLongPress(int keyCode,KeyEvent event);
⑤键盘快捷键事件发生: boolean onKeyShortcut(int keyCode,KeyEvent event);
⑥在组件上触发轨迹球屏事件: boolean onTrackballEvent(MotionEvent event);
*⑦当组件的焦点发生改变,和前面的6个不同,这个方法只能够在View中重写哦! protected void onFocusChanged(boolean gainFocus, int direction, Rect previously FocusedRect)
在Android中基于回调的事件处理机制使用场景有两个:
1)自定义view
当用户在GUI组件上激发某个事件时,组件有自己特定的方***负责处理该事件 通常用法:继承基本的GUI组件,重写该组件的事件处理方法,即自定义view 注意:在xml布局中使用自定义的view时,需要使用"全限定类名"
因为我们直接重写了Button的三个回调方法,当发生点击事件后就不需要我们在Java文件中进行事件***的绑定就可以完成回调,即组件会处理对应的事件,即事件由事件源(组件)自身处理!
2)基于回调的事件传播:
几乎所有的基于回调的事件处理方法都有一个boolean类型的返回值,该返回值用于标识该处理方法是否能完全处理该事件:
1.如果返回true,则表明该处理方法已完全处理了该事件,该事件不会被传播出去。
2.如果返回false,表明该处理方法未完全处理该事件,该事件会传播出去。
对于基于回调的事件处理传播而言,某组件上所发生的事情不仅激发该组件上的回调方法,也会触发该组件所在的Activity的回调方法——只要事件能传播到该Activity。
即是否向外传播取决于方法的返回值是时true还是false;
传播的顺序是: ***--->view组件的回调方法--->Activity的回调方法
参照Android开发者文档可知OnLongClickListener() ,OnFocusChangeListener(),OnKeyListener()等***的使用场景。而onMenuItemClickListener则监听当菜单项被点击后触发的onMenuItemClick事件,
参考资料
[1].Flame_Dream.Android开发系列10——事件处理机制.OL.
https://blog.csdn.net/Future_One/article/details/104779618
[2].李yi辉.Android中的事件处理总结-基于监听的事件处理.OL.
https://blog.csdn.net/yihuiworld/article/details/46308569
[3]. 输入事件概览 | Android 开发者 | Android Developers
https://developer.android.com/guide/topics/ui/ui-events?hl=zh-cn#EventHandlers
[4]. 3.2 基于回调的事件处理机制
https://www.runoob.com/w3cnote/android-tutorial-callback-event-handle.html