全面总结之 事件处理 篇

对于我们的 App 来说,界面有了,还得处理用户在界面上的各种操作,也就是说 App 必须为用户操作提供响应动作,这种响应动作就需要通过事件处理来完成了。

基于监听器的事件处理

在事件监听的处理模型中,主要设计以下三个对象:

  • 事件源(Event Source):事件发生的场所,主要是各个组件,例如按钮、窗口、菜单等等。
  • 事件(Event):事件封装了界面组件上发生的特定事情(通常是一次用户操作)。如果程序需要获得界面组件上所发生事件的相关信息,一般通过 Event 对象来取得。
  • 事件监听器(Event Listener):负责监听事件源所发生的事件,并对各种事件做出相应的响应。

当用户按下一个按钮或者单击某个菜单选项时,这些动作就会激发一个相应的事件,该事件就会出发事件源上注册的监听器,事件监听器调用对应的事件处理器来做出相应的响应。

Android 的事件处理机制是一种委派式的事件处理方式:普通组件将整个事件处理委托给特定的对象,当该事件源发生指定的事件时,就通知所委托的事件监听器,由事件监听器来处理这个事件。

基于监听的事件处理模型基本步骤如下:

  1. 获取普通界面组件(事件源),也就是被监听对象。
  2. 实现事件监听器类,该监听器类是一个特殊的 Java 类,必须实现一个 XXXListener 接口。
  3. 调用事件源的 setXXXListener 方法,将事件监听器注册给普通组件

当事件源上发生指定的事件时,Android 会触发事件监听器,由事件监听器调用相应的方法(事件处理器)来处理事件

最常用的,就是给一个按钮设置一个监听事件:

        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                
            }
        });

在这里:

  • 按钮 bt 就是事件源
  • View.OnClickListener() 就是监听器
  • setOnClickListener 就是给按钮 bt 注册监听器

当用户点击按钮的时候,会触发监听器,然后由监听器的 onClick 方法做出响应。

常用的事件监听器

Android 中的事件监听器有很多中,但有很多不是很常用,这里就常用的事件监听器列一下:

常用于 ListView 或者 GridView 的:

  • AdapterView.OnItemClickListener
  • AdapterView.OnItemLongClickListener

常用于 Spinner 的:

  • AdapterView.OnItemSelectedListener

常用于 ToggleButton 或者 CheckBox 的:

  • CompoundButton.OnCheckedChangeListener

常用于 Button 的:

  • View.OnClickListener
  • View.OnLongClickListener

常用于监控控件焦点变化的:

  • View.OnFocusChangeListener

常用于监听 SeekBar 拖动进度的:

  • SeekBar.OnSeekBarChangeListener

用于监控控件触摸的:

  • View.OnTouchListener

设置监听器的四种方法

  • 内部类绑定:
        Button bt = findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                
            }
        });
  • 创建监听器的子类,给组件绑定:
class MyClickListener implements View.OnClickListener{

    @Override
    public void onClick(View v) {
        ......
    }
}

Button bt = findViewById(R.id.bt);
bt.setOnClickListener(new MyClickListener());
  • 组件中绑定
    <Button
        android:id="@+id/bt"
        android:layout_width="match_parent"
        android:onClick="myClick"
        android:layout_height="wrap_content" />
    public void myClick(View view){
        ......
    }
  • Activity 实现监听接口
public class MainActivity extends Activity implements View.OnTouchListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.bt);
        button.setOnTouchListener(this);

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }
}

基于处理器的事件处理

Android 还定义了一些回调方法,以响应我们的操作,它们包括:

  • onKeyDown - 当一个新的按键事件发生时被调用。
  • onKeyUp - 当一个向上键事件发生时被调用。
  • onKeyLongPress - 当用户在该组件长按时被调用。
  • onTrackballEvent - 当一个跟踪球运动事件发生时被调用。
  • onTouchEvent - 当一个触摸屏移动事件发生时调用。
  • onFocusChanged -当视图获得或者丢失焦点时被调用。
  • onKeyShortcut - 当一个键盘快捷键事件发生时被调用。

还有两个对象记录着我们事件的一些元数据

  • KeyEvent - 记录按下按键的元数据
  • MotionEvent - 记录手指在屏幕上活动的元数据

例如我们重写 Activity 的 onKeyDown 方法:

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        Log.d("TTT", "Activity KeyDwon at " + event.getDownTime());

        return super.onKeyDown(keyCode, event);
    }

然后按下手机返回键,Log 如下:

07-17 15:06:00.423 13482-13482/com.li_xyz.touchtest D/TTT: Activity KeyDwon at 41278771

关于事件的分发传递,将在下一节讲解。