Android TV中按键事件和焦点处理总结

1.KeyEvent事件

keyEvent:

源码位于android.view下,包装管理所有按键有关输入的事件体系,KeyEvent和MotionEvent的分发流程一样,都是InputEvent的子类,都是从Activity开始的,KeyEvent主要有以下事件类型:

KeyEvent.KEYCODE_DPAD_UP; 上
KeyEvent.KEYCODE_DPAD_DOWN; 下
KeyEvent.KEYCODE_DPAD_LEFT;左
KeyEvent.KEYCODE_DPAD_RIGHT;右
KeyEvent.KEYCODE_DPAD_CENTER;确定键
KeyEvent.KEYCODE_DPAD_RIGHT; 右
KeyEvent.KEYCODE_XXX:数字键 (xx表示你按了数字几)
KeyEvent.KEYCODE_BACK; 返回键
KeyEvent.KEYCODE_HOME;房子键
KeyEvent.KEYCODE_A: A-Z,26个字母
KeyEvent.KEYCODE_MENU菜单键。
一般使用方法如:

   public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {
           //模拟器测试时键盘中的的Enter键,模拟ok键(推荐TV开发中使用蓝叠模拟器)
        case KeyEvent.KEYCODE_ENTER:
            break;
        case KeyEvent.KEYCODE_DPAD_CENTER:
            Toast("你按下中间键");
            break;

        case KeyEvent.KEYCODE_DPAD_DOWN:
            Toast("你按下下方向键");
        break;

        case KeyEvent.KEYCODE_DPAD_LEFT:
            Toast("你按下左方向键");
            break;

        case KeyEvent.KEYCODE_DPAD_RIGHT:
            Toast("你按下右方向键");
            break;

        case KeyEvent.KEYCODE_DPAD_UP:
            Toast("你按下上方向键");
            break;
    }
    return super.onKeyDown(keyCode, event);
}

或者可以复写onKeyUp();

2.KeyEvent事件分发

dispatchKeyEvent()

主要处理按键的分发。avtivity和view都拥有此方法,两种有所区别的,实际都是交给DecorView来处理。

public boolean dispatchKeyEvent(KeyEvent event) {
    // Let action bars open menus in response to the menu key prioritized over
    // the window handling it
    if (event.getKeyCode() == KeyEvent.KEYCODE_MENU &&
            mActionBar != null && mActionBar.onMenuKeyEvent(event)) {
        return true;
    }
    Window win = getWindow();
    if (win.superDispatchKeyEvent(event)) {
        return true;
    }
    View decor = mDecor;
    if (decor == null) decor = win.getDecorView();
    return event.dispatch(this, decor != null
            ? decor.getKeyDispatcherState() : null, this);
}

开发中上层使用如下:

 @Override    
 public boolean dispatchKeyEvent(KeyEvent event) {
        Log.d("dispatchKeyEvent","dispatchKeyEvent(), action=" + event.getAction() + " keycode=" + event.getKeyCode());
        return super.dispatchKeyEvent(event);
        }

使用效果和重写onKeyDown和onKeyUp类似。
开发中注意onKeyUp中点击的会多次调用的问题。
这里写图片描述

注意事件调用的流程
总结下整个流程:
首先触发dispatchKeyEvent()
再次onKeyDown 如果按下紧接着松开,则是两步
紧跟着触发dispatchKeyEvent
然后触发onUserInteraction
再次onKeyUp

3.焦点处理 Focus

  • requestFocus():强制设置一个焦点到指定的view或它的一个子类,(前提是android:focusable为true能够获得焦点)

    • android:focusable:设置一个控件能否获得焦点
    • android:background:设置在作为背景的drawable
    • android:nextFocusDown:定义下一个获得焦点的控件当按下键时
    • android:nextFocusUp:定义下一个获得焦点的控件当按上键时
    • android:nextFocusLeft:定义下一个获得焦点的控件当按左键时
    • android:nextFocusRight:定义下一个获得焦点的控件当按右键时

可以通过焦点事件变化操作view, View.setFocusable(true); 设置控件是否可以获得焦点,同时会触发 setOnFocusChangeListener()
焦点丢失问题

在组合控件中的焦点使用时
在使用ListView、GridView及RecyclerView时有时会出现,这时需要在xml中,添加

android:descendantFocusability="afterDescendants"

这里会有三种方式分别为

beforeDescendants:viewgroup会优先其子类控件而获取到焦点

afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点

blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点

类似效果:
这里写图片描述

焦点放大处理:
在RecyclerView中的item可以这样操作,比如焦点选中时放大,失去焦点后还原:

  holder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {    
              holder.itemView.animate().scaleX(1.05f).scaleY(1.2f).setDuration(300).start();
            } else {
                holder.itemView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(300).start();
            }
        }
    });

效果如图所示:
这里写图片描述

adb input 常见命令,可用于操作模拟器按键:
usage: input [text|keyevent]
input text
input keyevent
你可以输入:input text “字符串”
或一些按键事件:input keyevent Num
解锁:input keyevent 83
向上:input keyevent 19
向下:input keyevent 20
向左:input keyevent 21
向右:input keyevent 22
……
以下就是约定的按键键码:
0 –> “KEYCODE_UNKNOWN”
2 –> “KEYCODE_SOFT_RIGHT”
3 –> “KEYCODE_HOME”
4 –> “KEYCODE_BACK”
5 –> “KEYCODE_CALL”
6 –> “KEYCODE_ENDCALL”
7 –> “KEYCODE_0”
8 –> “KEYCODE_1”
9 –> “KEYCODE_2”
10 –> “KEYCODE_3”
11 –> “KEYCODE_4”
12 –> “KEYCODE_5”
13 –> “KEYCODE_6”
14 –> “KEYCODE_7”
15 –> “KEYCODE_8”
16 –> “KEYCODE_9”
17 –> “KEYCODE_STAR”
18 –> “KEYCODE_POUND”
19 –> “KEYCODE_DPAD_UP”
20 –> “KEYCODE_DPAD_DOWN”
21 –> “KEYCODE_DPAD_LEFT”
22 –> “KEYCODE_DPAD_RIGHT”
23 –> “KEYCODE_DPAD_CENTER”
24 –> “KEYCODE_VOLUME_UP”
25 –> “KEYCODE_VOLUME_DOWN”
26 –> “KEYCODE_POWER”
27 –> “KEYCODE_CAMERA”
28 –> “KEYCODE_CLEAR”
29 –> “KEYCODE_A”
30 –> “KEYCODE_B”
31 –> “KEYCODE_C”
32 –> “KEYCODE_D”
33 –> “KEYCODE_E”
34 –> “KEYCODE_F”
35 –> “KEYCODE_G”
36 –> “KEYCODE_H”
37 –> “KEYCODE_I”
38 –> “KEYCODE_J”
39 –> “KEYCODE_K”
40 –> “KEYCODE_L”
41 –> “KEYCODE_M”
42 –> “KEYCODE_N”
43 –> “KEYCODE_O”
44 –> “KEYCODE_P”
45 –> “KEYCODE_Q”
46 –> “KEYCODE_R”
47 –> “KEYCODE_S”
48 –> “KEYCODE_T”
49 –> “KEYCODE_U”
50 –> “KEYCODE_V”
51 –> “KEYCODE_W”
52 –> “KEYCODE_X”
53 –> “KEYCODE_Y”
54 –> “KEYCODE_Z”
55 –> “KEYCODE_COMMA”
56 –> “KEYCODE_PERIOD”
57 –> “KEYCODE_ALT_LEFT”
58 –> “KEYCODE_ALT_RIGHT”
59 –> “KEYCODE_SHIFT_LEFT”
60 –> “KEYCODE_SHIFT_RIGHT”
61 –> “KEYCODE_TAB”
62 –> “KEYCODE_SPACE”
63 –> “KEYCODE_SYM”
64 –> “KEYCODE_EXPLORER”
65 –> “KEYCODE_ENVELOPE”
66 –> “KEYCODE_ENTER”
67 –> “KEYCODE_DEL”
68 –> “KEYCODE_GRAVE”
69 –> “KEYCODE_MINUS”
70 –> “KEYCODE_EQUALS”
71 –> “KEYCODE_LEFT_BRACKET”
72 –> “KEYCODE_RIGHT_BRACKET”
73 –> “KEYCODE_BACKSLASH”
74 –> “KEYCODE_SEMICOLON”
75 –> “KEYCODE_APOSTROPHE”
76 –> “KEYCODE_SLASH”
77 –> “KEYCODE_AT”
78 –> “KEYCODE_NUM”
79 –> “KEYCODE_HEADSETHOOK”
80 –> “KEYCODE_FOCUS”
81 –> “KEYCODE_PLUS”
82 –> “KEYCODE_MENU”
83 –> “KEYCODE_NOTIFICATION”
84 –> “KEYCODE_SEARCH”
85 –> “TAG_LAST_KEYCODE”
示例:如模拟打开菜单
这里写图片描述
先记录这些,今后继续完善。

猜你喜欢

转载自blog.csdn.net/jun5753/article/details/78665886