一,事件处理
Android提供了两套事件处理机制:
1.基于监听的事件处理。
2.基于回调的事件处理。
基于回调的事件处理用于处理一些具有通用性的事件,基于监听的事件处理用于处理与具体业务相关的事件。
基于监听的事件处理
基于监听的事件处理是在指定view组件上绑定指定的监听器。比如点击事件:
可以以匿名内部类形式绑定监听器:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
或者:
// Create an anonymous implementation of OnClickListener
private OnClickListener mCorkyListener = new OnClickListener() {
public void onClick(View v) {
// do something when the button is clicked
}
};
protected void onCreate(Bundle savedValues) {
...
// Capture our button from layout
Button button = (Button)findViewById(R.id.corky);
// Register the onClick listener with the implementation above
button.setOnClickListener(mCorkyListener);
...
}
还可以将 OnClickListener 作为 Activity 的一部分来实现更为方便。这样可以避免加载额外的类和分配对象:
public class ExampleActivity extends Activity implements OnClickListener {
protected void onCreate(Bundle savedValues) {
...
Button button = (Button)findViewById(R.id.corky);
button.setOnClickListener(this);
}
// Implement the OnClickListener callback
public void onClick(View v) {
// do something when the button is clicked
}
...
}
view类声明监听器和执行点击事件中:
//监听器
public interface OnClickListener {
void onClick(View v);
}
//注册监听器 方法
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
//声明监听器
static class ListenerInfo {
public OnClickListener mOnClickListener;
}
//执行监听动作
public boolean performClick() {
final boolean result;
final ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);//调用监听器里的方法
result = true;
} else {
result = false;
}
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
return result;
}
基于回调的事件处理
基于回调的事件处理就是自定义UI组件或者Activity重写事件方法,比如View类和Activity的父类都实现了KeyEvent.Callback接口中的一系列回调函数,因此在自定义View或Activity中可以通过重写相关方法来实现特定功能:
KeyEvent.Callback接口:
public interface Callback {
//该返回值用于标识该处理函数是否能完全处理该事件
// 返回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);
}
重写相关方法:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onKeyDown(keyCode, event);
}
二,相关类概述
关于事件,android中有一个InputEvent类,它是针对所有事件的共有特点提取出来的一个统一的抽象类,此类结构简单,可以参看InputEvent .java 。其有两个子类:MotionEvent(位移事件)和KeyEvent(按键事件)。这两个类都定义了大量的常量,弄明白这些常量对读懂这两个类至关重要。还有InputDevice类,这个类包含关于输入设备定义的常量和其他一些常量。前面两个类中的常量几乎都是此类的输入设备的相关配置。
InputDevice类
输入设备:
public static final int SOURCE_CLASS_MASK = 0x000000ff;
public static final int SOURCE_CLASS_NONE = 0x00000000;
public static final int SOURCE_CLASS_BUTTON = 0x00000001;
public static final int SOURCE_CLASS_POINTER = 0x00000002;
public static final int SOURCE_CLASS_TRACKBALL = 0x00000004;
public static final int SOURCE_CLASS_POSITION = 0x00000008;
public static final int SOURCE_CLASS_JOYSTICK = 0x00000010;
public static final int SOURCE_UNKNOWN = 0x00000000;
public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON;
public static final int SOURCE_DPAD = 0x00000200 | SOURCE_CLASS_BUTTON;
public static final int SOURCE_GAMEPAD = 0x00000400 | SOURCE_CLASS_BUTTON;
public static final int SOURCE_TOUCHSCREEN = 0x00001000 | SOURCE_CLASS_POINTER;
public static final int SOURCE_MOUSE = 0x00002000 | SOURCE_CLASS_POINTER;
public static final int SOURCE_STYLUS = 0x00004000 | SOURCE_CLASS_POINTER;
public static final int SOURCE_BLUETOOTH_STYLUS =
0x00008000 | SOURCE_STYLUS;
public static final int SOURCE_TRACKBALL = 0x00010000 | SOURCE_CLASS_TRACKBALL;
public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION;
public static final int SOURCE_TOUCH_NAVIGATION = 0x00200000 | SOURCE_CLASS_NONE;
public static final int SOURCE_ROTARY_ENCODER = 0x00400000 | SOURCE_CLASS_NONE;
public static final int SOURCE_JOYSTICK = 0x01000000 | SOURCE_CLASS_JOYSTICK;
public static final int SOURCE_HDMI = 0x02000000 | SOURCE_CLASS_BUTTON;
public static final int SOURCE_ANY = 0xffffff00;
MotionEvent类
当用户触摸屏幕时将创建一个MotionEvent对象。MotionEvent包含关于发生触摸的位置和时间等细节信息。MotionEvent对象被传递到程序中合适的方法比如View对象的onTouchEvent()方法中。在这些方法中我们可以分析MotionEvent对象那个,以决定要执行的操作。
MotionEvent对象是与用户触摸相关的时间序列,该序列从用户首次触摸屏幕开始,经历手指在屏幕表面的任何移动,直到手指离开屏幕时结束。手指的初次触摸(ACTION_DOWN操作),滑动(ACTION_MOVE操作)和松开(ACTION_UP)都会创建MotionEvent对象。移动过程中会产生大量事件,每个事件都会产生对应的MotionEvent对象记录发生的操作,触摸的位置,使用的多大压力,触摸的面积,合适发生,以及最初的ACTION_DOWN和时发生等相关的信息。
action:触摸:
/**
* 按下
*/
public static final int ACTION_DOWN = 0;
/**
* 松开
*/
public static final int ACTION_UP = 1;
/**
* 移动
*/
public static final int ACTION_MOVE = 2;
/**
* 触摸动作取消
*/
public static final int ACTION_CANCEL = 3;
/**
* 触摸动作超出边界
*/
public static final int ACTION_OUTSIDE = 4;
/**
* 多点触摸按下动作
*/
public static final int ACTION_POINTER_DOWN = 5;
/**
* 多点离开动作
*/
public static final int ACTION_POINTER_UP = 6;
action:鼠标:
/**
* 鼠标在view上移动
*/
public static final int ACTION_HOVER_MOVE = 7;
/**
* 滚动
*/
public static final int ACTION_SCROLL = 8;
/**
* 鼠标进入view
*/
public static final int ACTION_HOVER_ENTER = 9;
/**
* 鼠标离开view
*/
public static final int ACTION_HOVER_EXIT = 10;
/**
* 鼠标按住按键
*/
public static final int ACTION_BUTTON_PRESS = 11;
/**
* 鼠标释放按键
*/
public static final int ACTION_BUTTON_RELEASE = 12;
action:特殊:这几个比较难以理解,建议阅读
android触控,先了解MotionEvent(一)
/**
* 动作位掩码
*/
public static final int ACTION_MASK = 0xff;
/**
* 指针位掩码
*/
public static final int ACTION_POINTER_INDEX_MASK = 0xff00;
/**
*
*/
public static final int ACTION_POINTER_INDEX_SHIFT = 8;
边缘:
/**
* 上边
*/
public static final int EDGE_TOP = 0x00000001;
/**
* 下边
*/
public static final int EDGE_BOTTOM = 0x00000002;
/**
* 左边
*/
public static final int EDGE_LEFT = 0x00000004;
/**
* 右边
*/
public static final int EDGE_RIGHT = 0x00000008;
触摸屏幕相关的常量:AXIS_打头
BUTTON鼠标按键:
/**
* 左键
*/
public static final int BUTTON_PRIMARY = 1 << 0;
/**
* 右键
*/
public static final int BUTTON_SECONDARY = 1 << 1;
/**
* 中间键
*/
public static final int BUTTON_TERTIARY = 1 << 2;
/**
* 后退键
*/
public static final int BUTTON_BACK = 1 << 3;