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

本文总结了Android TV开发中的按键事件和焦点处理,TV端的开发不同于手机开发,主要区别在于焦点的处理,常常会用到手机端很少用到的开发接口。了解这些不同的接口和区别,有助于很快的上手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();
            }
        }
    });

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

4.adb input 常见命令

可用于操作模拟器按键:
usage: input [text|keyevent]
input text
input keyevent <event_code>
你可以输入: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"

示例:如模拟打开菜单
这里写图片描述

5.总结

本文总结了Android TV端用到的最主要的焦点事件处理方式,在实现开发中可能还会遇到焦点的乱跳,这个需要大家进一步去如何处理好。

最后 送上Android TV端开发的常用开源库,希望对你有所帮助。

Android TV开发 开源项目收集

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小羊子说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值