互动规则介绍
????????现在的图形界面应用程序,都是通过事件来实现人机交互的。事件就是用户对图形界面的操作。在Android手机和平板电脑上,主要包括物理按键事件和触摸屏事件两大类。物理按键事件包括按下、抬起和长按等;触摸屏事件包括单击事件、长按事件和触摸事件等。 ????????在 Android 中提供了两种方式的事件处理,一种是基于监听的事件处理,另一种是基于回调的事件处理,下面分别进行介绍。
基于监听的事件处理
????????实现基于监听的事件处理,主要做法就是为 Android 的 UI 组件绑定特定的事件监听器。在事件监听的处理模型中,主要有以下 3 类对象:
- Event Source(事件源):即产生事件的来源,通常是各种组件,例如,按钮、窗口和菜单等
- Event(事件):事件中封装了 UI 组件上发生的特定事件的具体信息,如果监听器需要获取 UI 组件上所发生事件的相关信息,一般通过 Event 对象来传递。
- Event Listener(事件监听器):监听事件源所发生的事件,并对不同的事件做出相应的响应。
事件处理流程示意图如图所示?

基于回调的事件处理
????????实现基于回调的事件处理,主要做法就是重写 Android 组件特定的回调方法,或者重写Activity 的回调方法。从代码实现的角度来看,基于回调的事件处理模型更加简单。为了使用回调机制来处理 GUI 组件上所发生的事件,需要为该组件提供对应的事件处理方法,可以通过继承GUI 组件类,并重写该类的事件处理方法来实现。 ????????为了实现回调机制的事件处理,Android 为所有 GUI 组件都提供了一些事件处理的回调方法,例如,在 View 类中就包含了一些事件处理的回调方法,这些方法如表所示。?
?View类中事件处理的回调方法
方法 | 说明 | boolean onKeyDown(int keyCode, KeyEvent event) | 当用户在该组件上按下某个按键时触发 | boolean onKeyLongPress(int keyCode, KeyEvent event) | 当用户在该组件上长按某个按键时触发 | boolean onKeyShortcut(int keyCode, KeyEvent event) | 当一个键盘快捷键事件发生时触发 | boolean onKeyUp(int keyCode, KeyEvent event) | 当用户在该组件上松开某个按键时触发 | boolean onTouchEvent (MotionEvent event)? | 当用户在该组件上触发触摸屏事件时触发 | boolean onTrackballEvent(MotionEvent event) | 当用户在该组件上触发轨迹球事件时触发 |
????????一般来说,基于回调的事件处理方式可用于处理一些通用性的事件,事件处理的代码会比较简洁。但对于某些特定的事件,无法采用基于回调的事件处理方式实现时,就只能采用基于监听的事件处理方式了。
物理按键介绍
????????对于一个标准的 Android 设备,包含了多个能够触发事件的物理按键。例如,手机上的常用物理按键,如图所示。

?Android 设备常用物理按键能够触发的事件及其说明如表 所示。
物理按键 | KeyEvent | 说明 | 音量键 | KEYCODE_VOLUME_UP KEYCODE_VOLUME_DOWN | 控制当前上下文音量,如音乐播放器、手机铃声、通话 | 音量等返回键 | KEYCODE_BACK | 返回到前一个界面 | 菜单键 | KEYCODE_MENU | 显示当前应用的可用菜单 |
在Android 中处理物理按键事件时,常用的回调方法有以下 3 个:
- onKeyUp():当用户松开某个按键时触发该方法。
- onKeyDown():当用户按下(未松开)某个按键时触发该方法。
- onKeyLongPress():当用户长按某个按键时触发该方法。?
例子
?模拟b站退出的消息提示
?实现再按一次返回键退出程序
public class ExitKeyActivity extends AppCompatActivity {
private long exitTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exit_key);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//判断是否单击了返回键
if (keyCode == KeyEvent.KEYCODE_BACK) {
exit(); //创建并调用退出方法
return true; //拦截返回键
}
return super.onKeyDown(keyCode, event);
}
public void exit() {
if ((System.currentTimeMillis() - exitTime) > 2000) { //判断按键时间差是否大于2秒
Toast.makeText(getApplicationContext(),
"再按一次返回键退出", Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
System.exit(0); //销毁,并强制退出
}
}
}
|