KeyEvent分发机制

先说重要点:
要点一: 截断事件

TV:通过 dispatchKeyEvent 分发事件,返回 false 或者 true 截断本类和子类中的事件分发(onKeyDown无法接收到事件),截取某个按键可返回 false 和 ture 都能截断这个按键向下分发,对上层没有影响。

​Phone:和上同理知识分发事件的方法为 dispatchTouchEvent ,由onTouchEvent 处理。

要点二: 消耗事件

​ KeyEvent 事件处理只有两个地方,一个是 Activity,另一个则是具体的View,返回true 表示事件已消耗,返回 false 则表示事件还在。

​ 当KeyEvent 事件分到具体的子 View 的 dispatchEvent() 里时,View 回去先去看有没有设置 OnKeyListener监听器吗,有则回调 OnKeyListener.onKey()方法来处理事件,当返回 false 或者为空的时候,VIew会通过调用KeyEvent的dispatch()来回调View自己的onKeyDown/Up()来处理事件。

调用使用 OnKeyListener 监听器👇

MButton mButton = new MButton(this);
//如果不设置 OnKeyListener 监听器,事件将由 onKeyDown() 方法处理事件
mButton.setOnKeyListener(new View.OnKeyListener() {
   
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
   
        return false;
    }
});

如果不想一个事件执行两次,就返回 true

要点二:

​ 如果你在本类中重写了dispatchKeyEvent 方法,记得返回父类的 dispatchKeyEvent(return super.dispatchKeyEvent),因为你重写的 dispatchKeyEvent 没有事件分发,这会导致下面调用的无法接收到事件,相当于截取了全部事件。

运行流程:

请添加图片描述

(PhoneWindow$)DecorView的dispatchKeyEvent

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
   
    final int keyCode = event.getKeyCode();
    final int action = event.getAction();
    final boolean isDown = action == KeyEvent.ACTION_DOWN;

    if (isDown && (event.getRepeatCount() == 0)) {
   
        // First handle chording of panel key: if a panel key is held
        // but not released, try to execute a shortcut in it.
        if ((mWindow.mPanelChordingKey > 0) && (mWindow.mPanelChordingKey != keyCode)) {
   
            boolean handled = dispatchKeyShortcutEvent(event);
            if (handled) {
   
                return true;
            }
        }

        // If a panel is open, perform a shortcut on it without the
        // chorded panel key
        if ((mWindow.mPreparedPanel != null) && mWindow.mPreparedPanel.isOpen) {
   
            if (mWindow.performPanelShortcut(mWindow.mPreparedPanel, keyCode, event
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值