源码解析Android中的事件处理

一,事件处理

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;
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值