Skip to content

事件处理

Android 的事件处理机制分为基于回调和基于监听的事件处理 。

  • 基于监听的事件处理:为Android界面组件绑定特定的事件监听器,在事件监听器的特定方法里编写事件处理代码,当事件发生后,监听器会自动调用方法来处理事件。
  • 基于回调的事件处理:重写Android组件类以及它继承的特定回调方法,当事件发生后,由系统自动识别事件并调用对应的回调方法。

基于监听的事件处理

  • EventSource(事件源):产生事件的组件即事件发生的场所,如按钮、菜单等。
  • Event(事件):具体某一操作的详细描述,事件封装了操作的相关信息,如果想获得事件源上所发生事件的相关信息,可通过Event对象来取得,例如按键事件按下的是哪个键、触摸事件发生的位置等。
  • EventListener(事件监听器):负责监听用户在事件源上的操作,并调用事件处理器对用户的各种操作做出相应的响应。事件监听器中可包含多个事件处理器,一个事件处理器实际上就是一个事件处理方法。

这是一种委托式事件处理:普通组件(事件源)将整个事件处理委托给特定的对象(事件监听器)。当该事件源发生指定的事情时,系统自动生成事件对象,并通知所委托的事件监听器,由事件监听器相应的事件处理器来处理这个事件。

常用的监听器接口:

除了单击和状态改变,Android还包含很多其他的监听器接口,补充如下:

  • OnClickListener:单击事件,需要重写 onClick(View v) 方法。
  • OnLongClickListener:长按事件,需要重写 onLongClick(View v) 方法。
  • OnFocusChangeListener:焦点改变事件,需要重写 onFocusChange(View v, Boolean hasFocus) 方法。
  • OnKeyListener:键盘事件,需要重写 onKey(View v, int keyCode, KeyEvent event) 方法。
  • OnTouchListener:触摸事件,需要重写 onTouch(View v, MotionEvent event) 方法。
  • OnCreateContexMenuListener:上下文菜单显示事件,需要重写 onCreateContexMenu(ContexMenu menu, View v, ContexMenuInfo info) 方法。
  • OnCheckedChangeListener:状态改变事件,需要重写 onCheckedChanged(CompoundButton compoundButton, boolean b) 方法。

实现方法

基于监听的事件处理共有 5 种实现方法 :

1. 使用内部类处理事件

优点: 可在Activity中复用此监听器类监听不同控件的同类事件;可直接访问所有界面组件。

  • 在控件所属Activity类中创建一个监听器类,该类需实现某个XxxListerner接口。
  • 在监听器类中重写与监听事件对应的方法。
  • 获取事件源(触发事件的界面组件对象)。
  • 通过事件源调用setXxxListener()方法为事件源设置事件监听器对象。

2. 使用匿名内部类处理事件

优点: 代码简洁;可直接访问所有界面组件。

缺点: 不能复用此监听器类。

  • 获取事件源(触发事件的界面组件对象)。
  • 通过事件源调用setXxxListener()方法为事件源设置事件监听器对象。
  • 创建匿名内部监听器XxxListerner接口对象(重写与监听事件对应的方法),作为setXxxListener()方法调用的实际参数。

3. 使用Activity类自身处理事件

优点: 代码简洁;可直接访问所有界面组件。

  • 让当前Activity类实现监听器XxxListerner接口。
  • 在当前Activity类中重写与监听事件对应的方法。
  • 获取事件源(触发事件的界面组件对象)。
  • 通过事件源调用setXxxListener()方法为事件源设置事件监听器对象(通常传入 this)。

4. 直接将事件绑定到标签

优点: 可复用此事件处理方法;代码简洁。

缺点: 应用范围小,因为控件的包含的事件属性较少(只有onClick事件属性),绝大多数事件没有对应的事件属性。

  • 当前Activity类定义一个事件处理方法,传入一个View类对象作为方法参数。
  • 在布局文件中,为触发事件的控件需要设置相应的事件属性(例如 android:onClick ),属性值为事件处理方法名。

5. 使用外部类处理事件

优点: 可复用此监听器类。

缺点: 当事件涉及控件较多时,参数导入较麻烦。

  • 自定义一个外部类,该类实现某个XxxListerner接口。
  • 在外部类中定义构造函数,并将事件涉及的所有控件作为参数导入。
  • 在外部类中重写与监听事件对应的方法。
  • 获取事件源(触发事件的界面组件对象)。
  • 通过事件源调用setXxxListener()方法为事件源设置事件监听器对象,该对象是外部类的对象。