目录
- 前言
- 开发思路
- 先上效果
- 开发细节
- 使用RawKeyboardListener
- Provider层对事件进行处理
- 注意
- 总结
- 文件参考
- TV keyCode详解
前言
最近公司有了新的业务,把现有Flutter Android项目应用到TV上去,这不,Asscre的活就来了。
本文详细说明Flutter for TV的两种实现方式,能力有限,不足之处欢迎指点,哈哈哈
开发思路
在开发之前,我们先设定一下我们的思路。
即,如何对原有程序代码侵入式最小、性能最佳、可玩性更高做出设定。
那么,通过上面的设定,我们在Flutter Widget中就发现了两个东西:
- RawKeyboardListener
- InkWell和其他Android TV配置
先上效果
可玩性、可塑性更高的RawKeyboardListener解决方案效果
对原有程序修改最小的InkWell和其他Android TV配置解决方案效果
开发细节
可玩性、可塑性更高的RawKeyboardListener解决方案
使用RawKeyboardListener
RawKeyboardListener( | |
focusNode: d.focusNode, // 配置focusNode | |
onKey: (RawKeyEvent event) => | |
context.read<HomePageContentWidgetProvider>().focusEventHandler(event, context, d), // 对特殊事件进行监听和处理 | |
child: Container( | |
height:, | |
width:, | |
decoration: BoxDecoration( | |
border: Border.all( | |
width:, | |
color: d.focusNode.hasFocus ? Colors.blue : Colors.transparent), | |
borderRadius: BorderRadius.circular(), | |
color: Colors.white.withAlpha(), | |
), | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
crossAxisAlignment: CrossAxisAlignment.center, | |
children: [ | |
Image.asset( | |
d.img, | |
height:, | |
), | |
SizedBox(height:), | |
Text( | |
d.name, | |
style: TextStyle( | |
color: Colors.white, | |
fontSize:, | |
), | |
), | |
], | |
), | |
), | |
), |
Provider层对事件进行处理
import 'package:flutter/material.dart'; | |
import 'package:flutter/services.dart'; | |
import 'package:tv_test/pages/memory_page/memory_page.dart'; | |
import 'package:flutter_screenutil/flutter_screenutil.dart'; | |
class HomePageContentWidgetProvider | |
with ChangeNotifier { | |
bool init = false; | |
double maxWScreen =; // 按钮距离屏幕右侧最大边界 | |
double minWScreen =.w; // 按钮距离屏幕最左侧距离边界 | |
final List<HomePageMakeBtn> makeBtnList = [ | |
HomePageMakeBtn('lib/assets/img/youtube.png', 'You Tube', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/apple.png', 'Apple', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/facebook.png', 'Facebook', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/douyin.png', 'Tik Tok', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/mi.png', 'MI', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/huawei.png', 'Hua Wei', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/youtube.png', 'TTT', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/apple.png', 'DDDD', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/facebook.png', 'FFFF', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/douyin.png', 'AAAA', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/mi.png', 'QQQQQ', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/huawei.png', 'WWWW', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/youtube.png', 'EEEEE', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/apple.png', 'RRRRR', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/facebook.png', 'YYYYYY', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/douyin.png', 'UUUUUU', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/mi.png', 'SSSSS', '', FocusNode()), | |
HomePageMakeBtn('lib/assets/img/huawei.png', 'VVVV', '', FocusNode()), | |
]; | |
HomePageContentWidgetProvider(BuildContext context) { | |
maxWScreen = MediaQuery.of(context).size.width -.w; | |
// setMakeFocusAddListener(); | |
if (!init) { | |
makeBtnList.first.focusNode.requestFocus(); | |
init = true; | |
} | |
} | |
setMakeFocusAddListener() { | |
for (int i =; i < makeBtnList.length; i++) { | |
makeBtnList[i].focusNode.addListener(() { | |
if (makeBtnList[i].focusNode.hasFocus) { | |
// notifyListeners(); | |
print( | |
'====${makeBtnList[i].name} : ${makeBtnList[i].focusNode.hasFocus}'); | |
} | |
}); | |
} | |
} | |
setMakeFocusDispose() { | |
for (var item in makeBtnList) { | |
item.focusNode.removeListener(() {}); | |
item.focusNode.dispose(); | |
} | |
} | |
focusEventHandler( | |
RawKeyEvent event, BuildContext context, HomePageMakeBtn param) async { | |
/// 只处理按键按下的事件 | |
if (event.data is RawKeyEventDataAndroid && | |
event.runtimeType.toString() == 'RawKeyDownEvent') { | |
CustomRawKeyEventDataAndroid _d = | |
CustomRawKeyEventDataAndroid.format(event.data); | |
/// 对按下确定键和中心键进行处理 | |
if (_d.keyCode == || _d.keyCode == 66) { | |
Navigator.of(context).push( | |
MaterialPageRoute(builder: (_) => MemoryPage(title: param.name))); | |
} else { | |
// for (var e in makeBtnList) { | |
// print('${e.name} : ${e.focusNode.hasFocus}'); | |
// } | |
/// 对左键进行处理 | |
if (_d.keyCode ==) { | |
await keyCodeDpadLeft(context, param); | |
} | |
/// 对右键进行处理 | |
if (_d.keyCode ==) { | |
await keyCodeDpadRight(context, param); | |
} | |
notifyListeners(); | |
} | |
} | |
} | |
/// 对左键进行处理 | |
keyCodeDpadLeft(BuildContext context, HomePageMakeBtn param) async { | |
/// 首位边界处理 | |
final int _idx = makeBtnList.indexWhere((e) => e == param); | |
if (_idx ==) return; | |
final int _nextIndex = _idx +; | |
if ((_nextIndex %) == 1) { | |
HomePageMakeBtn _nextNode = makeBtnList[_idx -]; | |
print(_nextNode.name); | |
await Future.delayed(const Duration(milliseconds:)); | |
_nextNode.focusNode.requestFocus(); | |
} | |
} | |
/// 对右键进行处理 | |
keyCodeDpadRight(BuildContext context, HomePageMakeBtn param) async { | |
final int _idx = makeBtnList.indexWhere((e) => e == param); | |
/// 末位边界处理 | |
if (_idx == (makeBtnList.length -)) return; | |
final int _nextIndex = _idx +; | |
if ((_nextIndex %) == 0) { | |
HomePageMakeBtn _nextNode = makeBtnList[_nextIndex]; | |
await Future.delayed(const Duration(milliseconds:)); | |
_nextNode.focusNode.requestFocus(); | |
} | |
} | |
void dispose() { | |
setMakeFocusDispose(); | |
super.dispose(); | |
} | |
} | |
class HomePageMakeBtn { | |
final String img; | |
final String name; | |
final String routerName; | |
final FocusNode focusNode; | |
HomePageMakeBtn(this.img, this.name, this.routerName, this.focusNode); | |
} | |
class CustomRawKeyEventDataAndroid { | |
final int flags; | |
final int codePoint; | |
final int plainCodePoint; | |
/// case: KEY_UP | |
/// case: KEY_DOWN | |
/// case: KEY_LEFT | |
/// case: KEY_RIGHT | |
/// case: KEY_CENTER | |
final int keyCode; | |
final int scanCode; | |
final int metaState; | |
CustomRawKeyEventDataAndroid(this.flags, this.codePoint, this.plainCodePoint, | |
this.keyCode, this.scanCode, this.metaState); | |
static CustomRawKeyEventDataAndroid format(d) { | |
return CustomRawKeyEventDataAndroid(d.flags, d.codePoint, d.plainCodePoint, | |
d.keyCode, d.scanCode, d.metaState); | |
} | |
} |
注意
我们可以看到在处理左键和右键的时候我们用了
这是为什么呢?
那是因为在实际效果中,我们requestFocus操作的时候,Flutter的机制会首先触发一次requestFocus,然后再触发一次requestFocus,一共两次,这就与我们的预想就有冲突了。
例如:
使用按键末尾向右时,系统触发的focus到UUUUU这个按钮,我们的实际预想的是到YYYYY即可。
使用按键首位向左时,同样会跨两个focus。
目前Asscre并没有找到很好的解决方案,但使用await Future delayed可以舒缓一下这不人性的操作。
对原有程序修改最小的InkWell和其他Android TV配置解决方案
首先,我们需要在AndroidManifest.xml 设置LEANBACK_LAUNCHER告诉平台我们的程序是一个电视应用程序
<intent-filter> | |
<action android:name="android.intent.action.MAIN"/> | |
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/> // 新增这一句 | |
<category android:name="android.intent.category.LAUNCHER"/> | |
</intent-filter> |
然后,我们在Main入口文件中添加 Shortcuts用于我们的程序响应我们的遥控器指令。
return Shortcuts( | |
shortcuts: <LogicalKeySet, Intent>{ | |
LogicalKeySet(LogicalKeyboardKey.select): ActivateIntent(), | |
}, | |
child: MaterialApp( | |
... | |
); |
最后,使用InkWell来获取焦点设置用户遥控点击的效果,其中focusColor帮助我们提醒用户此时的按钮位置。
return Material( | |
color: Colors.white.withAlpha(), | |
child: InkWell( | |
focusColor: Colors.deepOrange.withAlpha(), | |
onTap: () => Navigator.of(context) | |
.push(MaterialPageRoute(builder: (_) => MemoryPage(title: d.name))), | |
child: SizedBox( | |
height:, | |
width:, | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
crossAxisAlignment: CrossAxisAlignment.center, | |
children: [ | |
Image.asset( | |
d.img, | |
height:, | |
), | |
SizedBox(height:), | |
Text( | |
d.name, | |
style: TextStyle( | |
color: Colors.white, | |
fontSize:, | |
), | |
), | |
], | |
), | |
), | |
), | |
); |
总结
上述两种解决方案中,大家可以根据自己(boss)的喜好或者业务需求选择一种使用。
在需要复杂的自定义的业务情况下,推荐使用RawKeyboardListener的解决方案,可以做出很多酷炫的效果,譬如按键事件触发时,focus住的widget可以做出放大、渐变等等效果,这有助于提升用户的体验。
但,要是在现有的业务逻辑上,在少量调整后就可使用上述中的InkWell的解决方案。
文件参考
TV keyCode详解
name | keycode | 说明 |
KEYCODE_UNKNOWN | 0 | |
--------------------------------------- | ----- | -------------- |
KEYCODE_SOFT_LEFT | 1 | |
KEYCODE_SOFT_RIGHT | 2 | |
KEYCODE_HOME | 3 | HOME键 |
KEYCODE_BACK | 4 | 返回键 |
KEYCODE_CALL | 5 | 拨号键 |
KEYCODE_ENDCALL | 6 | 挂机键 |
KEYCODE_0 | 7 | |
KEYCODE_1 | 8 | |
KEYCODE_2 | 9 | |
KEYCODE_3 | 10 | |
KEYCODE_4 | 11 | |
KEYCODE_5 | 12 | |
KEYCODE_6 | 13 | |
KEYCODE_7 | 14 | |
KEYCODE_8 | 15 | |
KEYCODE_9 | 16 | |
KEYCODE_STAR | 17 | 按键 * |
KEYCODE_POUND | 18 | 按键 # |
KEYCODE_DPAD_UP | 19 | 向上 |
KEYCODE_DPAD_DOWN | 20 | 向下 |
KEYCODE_DPAD_LEFT | 21 | 向左 |
KEYCODE_DPAD_RIGHT | 22 | 向右 |
KEYCODE_DPAD_CENTER | 23 | 确定键 |
KEYCODE_VOLUME_UP | 24 | 音量增加键 |
KEYCODE_VOLUME_DOWN | 25 | 音量减小键 |
KEYCODE_POWER | 26 | 电源键 |
KEYCODE_CAMERA | 27 | 拍照键 |
KEYCODE_CLEAR | 28 | |
KEYCODE_A | 29 | |
KEYCODE_B | 30 | |
KEYCODE_C | 31 | |
KEYCODE_D | 32 | |
KEYCODE_E | 33 | |
KEYCODE_F | 34 | |
KEYCODE_G | 35 | |
KEYCODE_H | 36 | |
KEYCODE_I | 37 | |
KEYCODE_J | 38 | |
KEYCODE_K | 39 | |
KEYCODE_L | 40 | |
KEYCODE_M | 41 | |
KEYCODE_N | 42 | |
KEYCODE_O | 43 | |
KEYCODE_P | 44 | |
KEYCODE_Q | 45 | |
KEYCODE_R | 46 | |
KEYCODE_S | 47 | |
KEYCODE_T | 48 | |
KEYCODE_U | 49 | |
KEYCODE_V | 50 | |
KEYCODE_W | 51 | |
KEYCODE_X | 52 | |
KEYCODE_Y | 53 | |
KEYCODE_Z | 54 | |
KEYCODE_COMMA | 55 | 按键 , |
KEYCODE_PERIOD | 56 | 按键 . |
KEYCODE_ALT_LEFT | 57 | |
KEYCODE_ALT_RIGHT | 58 | |
KEYCODE_SHIFT_LEFT | 59 | |
KEYCODE_SHIFT_RIGHT | 60 | |
KEYCODE_TAB | 61 | Tab键 |
KEYCODE_SPACE | 62 | 空格键 |
KEYCODE_SYM | 63 | |
KEYCODE_EXPLORER | 64 | |
KEYCODE_ENVELOPE | 65 | |
KEYCODE_ENTER | 66 | 回车键 |
KEYCODE_DEL | 67 | 退格键 |
KEYCODE_GRAVE | 68 | 按键 ` |
KEYCODE_MINUS | 69 | 按键- |
KEYCODE_EQUALS | 70 | 按键 = |
KEYCODE_LEFT_BRACKET | 71 | 按键 [ |
KEYCODE_RIGHT_BRACKET | 72 | 按键 ] |
KEYCODE_BACKSLASH | 73 | 按键 \ |
KEYCODE_SEMICOLON | 74 | 按键 , |
KEYCODE_APOSTROPHE | 75 | 按键 ''单引号 |
KEYCODE_SLASH | 76 | 按键 / |
KEYCODE_AT | 77 | 按键 @ |
KEYCODE_NUM | 78 | |
KEYCODE_HEADSETHOOK | 79 | |
KEYCODE_FOCUS | 80 | 拍照对焦键 |
KEYCODE_PLUS | 81 | 按键+ |
KEYCODE_MENU | 82 | 菜单键 |
KEYCODE_NOTIFICATION | 83 | 通知键 |
KEYCODE_SEARCH | 84 | |
KEYCODE_MEDIA_PLAY_PAUSE | 85 | 多媒体键 播放/暂停 |
KEYCODE_MEDIA_STOP | 86 | 多媒体键 暂停 |
KEYCODE_MEDIA_NEXT | 87 | 多媒体键 下一首 |
KEYCODE_MEDIA_PREVIOUS | 88 | 多媒体键 上一首 |
KEYCODE_MEDIA_REWIND | 89 | 多媒体键 快退 |
KEYCODE_MEDIA_FAST_FORWARD | 90 | 多媒体键 快进 |
KEYCODE_MUTE | 91 | 话筒静音键 |
KEYCODE_PAGE_UP | 92 | 向上翻页键 |
KEYCODE_PAGE_DOWN | 93 | 向下翻页键 |
KEYCODE_PICTSYMBOLS | 94 | |
KEYCODE_SWITCH_CHARSET | 95 | |
KEYCODE_BUTTON_A | 96 | |
KEYCODE_BUTTON_B | 97 | |
KEYCODE_BUTTON_C | 98 | |
KEYCODE_BUTTON_X | 99 | |
KEYCODE_BUTTON_Y | 100 | |
KEYCODE_BUTTON_Z | 101 | |
KEYCODE_BUTTON_L1 | 102 | |
KEYCODE_BUTTON_R1 | 103 | |
KEYCODE_BUTTON_L2 | 104 | |
KEYCODE_BUTTON_R2 | 105 | |
KEYCODE_BUTTON_THUMBL | 106 | |
KEYCODE_BUTTON_THUMBR | 107 | |
KEYCODE_BUTTON_START | 108 | |
KEYCODE_BUTTON_SELECT | 109 | |
KEYCODE_BUTTON_MODE | 110 | |
KEYCODE_ESCAPE | 111 | ESC键 |
KEYCODE_FORWARD_DEL | 112 | 删除键 |
KEYCODE_CTRL_LEFT | 113 | |
KEYCODE_CTRL_RIGHT | 114 | |
KEYCODE_CAPS_LOCK | 115 | 大写锁定键 |
KEYCODE_SCROLL_LOCK | 116 | |
KEYCODE_META_LEFT | 117 | |
KEYCODE_META_RIGHT | 118 | |
KEYCODE_FUNCTION | 119 | |
KEYCODE_SYSRQ | 120 | |
KEYCODE_BREAK | 121 | Break/Pause键 |
KEYCODE_MOVE_HOME | 122 | 光标移动到开始键 |
KEYCODE_MOVE_END | 123 | 光标移动到末尾键 |
KEYCODE_INSERT | 124 | |
KEYCODE_FORWARD | 125 | |
KEYCODE_MEDIA_PLAY | 126 | 多媒体键 播放 |
KEYCODE_MEDIA_PAUSE | 127 | 多媒体键 暂停 |
KEYCODE_MEDIA_CLOSE | 128 | 多媒体键 关闭 |
KEYCODE_MEDIA_EJECT | 129 | 多媒体键 弹出 |
KEYCODE_MEDIA_RECORD | 130 | 多媒体键 录音 |
KEYCODE_F1 | 131 | |
KEYCODE_F2 | 132 | |
KEYCODE_F3 | 133 | |
KEYCODE_F4 | 134 | |
KEYCODE_F5 | 135 | |
KEYCODE_F6 | 136 | |
KEYCODE_F7 | 137 | |
KEYCODE_F8 | 138 | |
KEYCODE_F9 | 139 | |
KEYCODE_F10 | 140 | |
KEYCODE_F11 | 141 | |
KEYCODE_F12 | 142 | |
KEYCODE_NUM_LOCK | 143 | 小键盘锁 |
KEYCODE_NUMPAD_0 | 144 | |
KEYCODE_NUMPAD_1 | 145 | |
KEYCODE_NUMPAD_2 | 146 | |
KEYCODE_NUMPAD_3 | 147 | |
KEYCODE_NUMPAD_4 | 148 | |
KEYCODE_NUMPAD_5 | 149 | |
KEYCODE_NUMPAD_6 | 150 | |
KEYCODE_NUMPAD_7 | 151 | |
KEYCODE_NUMPAD_8 | 152 | |
KEYCODE_NUMPAD_9 | 153 | |
KEYCODE_NUMPAD_DIVIDE | 154 | |
KEYCODE_NUMPAD_MULTIPLY | 155 | |
KEYCODE_NUMPAD_SUBTRACT | 156 | |
KEYCODE_NUMPAD_ADD | 157 | |
KEYCODE_NUMPAD_DOT | 158 | |
KEYCODE_NUMPAD_COMMA | 159 | |
KEYCODE_NUMPAD_ENTER | 160 | |
KEYCODE_NUMPAD_EQUALS | 161 | |
KEYCODE_NUMPAD_LEFT_PAREN | 162 | |
KEYCODE_NUMPAD_RIGHT_PAREN | 163 | |
KEYCODE_VOLUME_MUTE | 164 | 扬声器静音键 |
KEYCODE_INFO | 165 | |
KEYCODE_CHANNEL_UP | 166 | |
KEYCODE_CHANNEL_DOWN | 167 | |
KEYCODE_ZOOM_IN | 168 | 放大键 |
KEYCODE_ZOOM_OUT | 169 | 缩小键 |
KEYCODE_TV | 170 | |
KEYCODE_WINDOW | 171 | |
KEYCODE_GUIDE | 172 | |
KEYCODE_DVR | 173 | |
KEYCODE_BOOKMARK | 174 | |
KEYCODE_CAPTIONS | 175 | |
KEYCODE_SETTINGS | 176 | |
KEYCODE_TV_POWER | 177 | |
KEYCODE_TV_INPUT | 178 | |
KEYCODE_STB_POWER | 179 | |
KEYCODE_STB_INPUT | 180 | |
KEYCODE_AVR_POWER | 181 | |
KEYCODE_AVR_INPUT | 182 | |
KEYCODE_PROG_RED | 183 | |
KEYCODE_PROG_GREEN | 184 | |
KEYCODE_PROG_YELLOW | 185 | |
KEYCODE_PROG_BLUE | 186 | |
KEYCODE_APP_SWITCH | 187 | |
KEYCODE_BUTTON_1 | 188 | |
KEYCODE_BUTTON_2 | 189 | |
KEYCODE_BUTTON_3 | 190 | |
KEYCODE_BUTTON_4 | 191 | |
KEYCODE_BUTTON_5 | 192 | |
KEYCODE_BUTTON_6 | 193 | |
KEYCODE_BUTTON_7 | 194 | |
KEYCODE_BUTTON_8 | 195 | |
KEYCODE_BUTTON_9 | 196 | |
KEYCODE_BUTTON_10 | 197 | |
KEYCODE_BUTTON_11 | 198 | |
KEYCODE_BUTTON_12 | 199 | |
KEYCODE_BUTTON_13 | 200 | |
KEYCODE_BUTTON_14 | 201 | |
KEYCODE_BUTTON_15 | 202 | |
KEYCODE_BUTTON_16 | 203 | |
KEYCODE_LANGUAGE_SWITCH | 204 | |
KEYCODE_MANNER_MODE | 205 | |
KEYCODE_3D_MODE | 206 | |
KEYCODE_CONTACTS | 207 | |
KEYCODE_CALENDAR | 208 | |
KEYCODE_MUSIC | 209 | |
KEYCODE_CALCULATOR | 210 | |
KEYCODE_ZENKAKU_HANKAKU | 211 | |
KEYCODE_EISU | 212 | |
KEYCODE_MUHENKAN | 213 | |
KEYCODE_HENKAN | 214 | |
KEYCODE_KATAKANA_HIRAGANA | 215 | |
KEYCODE_YEN | 216 | |
KEYCODE_RO | 217 | |
KEYCODE_KANA | 218 | |
KEYCODE_ASSIST | 219 | |
KEYCODE_BRIGHTNESS_DOWN | 220 | |
KEYCODE_BRIGHTNESS_UP | 221 | |
KEYCODE_MEDIA_AUDIO_TRACK | 222 | |
KEYCODE_SLEEP | 223 | |
KEYCODE_WAKEUP | 224 | |
KEYCODE_PAIRING | 225 | |
KEYCODE_MEDIA_TOP_MENU | 226 | |
KEYCODE_11 | 227 | |
KEYCODE_12 | 228 | |
KEYCODE_LAST_CHANNEL | 229 | |
KEYCODE_TV_DATA_SERVICE | 230 | |
KEYCODE_VOICE_ASSIST | 231 | |
KEYCODE_TV_RADIO_SERVICE | 232 | |
KEYCODE_TV_TELETEXT | 233 | |
KEYCODE_TV_NUMBER_ENTRY | 234 | |
KEYCODE_TV_TERRESTRIAL_ANALOG | 235 | |
KEYCODE_TV_TERRESTRIAL_DIGITAL | 236 | |
KEYCODE_TV_SATELLITE | 237 | |
KEYCODE_TV_SATELLITE_BS | 238 | |
KEYCODE_TV_SATELLITE_CS | 239 | |
KEYCODE_TV_SATELLITE_SERVICE | 240 | |
KEYCODE_TV_NETWORK | 241 | |
KEYCODE_TV_ANTENNA_CABLE | 242 | |
KEYCODE_TV_INPUT_HDMI_1 | 243 | |
KEYCODE_TV_INPUT_HDMI_2 | 244 | |
KEYCODE_TV_INPUT_HDMI_3 | 245 | |
KEYCODE_TV_INPUT_HDMI_4 | 246 | |
KEYCODE_TV_INPUT_COMPOSITE_1 | 247 | |
KEYCODE_TV_INPUT_COMPOSITE_2 | 248 | |
KEYCODE_TV_INPUT_COMPONENT_1 | 249 | |
KEYCODE_TV_INPUT_COMPONENT_2 | 250 | |
KEYCODE_TV_INPUT_VGA_1 | 251 | |
KEYCODE_TV_AUDIO_DESCRIPTION | 252 | |
KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP | 253 | |
KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN | 254 | |
KEYCODE_TV_ZOOM_MODE | 255 | |
KEYCODE_TV_CONTENTS_MENU | 256 | |
KEYCODE_TV_MEDIA_CONTEXT_MENU | 257 | |
KEYCODE_TV_TIMER_PROGRAMMING | 258 | |
KEYCODE_HELP | 259 | |
KEYCODE_NAVIGATE_PREVIOUS | 260 | |
KEYCODE_NAVIGATE_NEXT | 261 | |
KEYCODE_NAVIGATE_IN | 262 | |
KEYCODE_NAVIGATE_OUT | 263 | |
KEYCODE_STEM_PRIMARY | 264 | |
KEYCODE_STEM_1 | 265 | |
KEYCODE_STEM_2 | 266 | |
KEYCODE_STEM_3 | 267 | |
KEYCODE_DPAD_UP_LEFT | 268 | |
KEYCODE_DPAD_DOWN_LEFT | 269 | |
KEYCODE_DPAD_UP_RIGHT | 270 | |
KEYCODE_DPAD_DOWN_RIGHT | 271 | |
KEYCODE_MEDIA_SKIP_FORWARD | 272 | |
KEYCODE_MEDIA_SKIP_BACKWARD | 273 | |
KEYCODE_MEDIA_STEP_FORWARD | 274 | |
KEYCODE_MEDIA_STEP_BACKWARD | 275 | |
KEYCODE_SOFT_SLEEP | 276 | |
KEYCODE_CUT | 277 | |
KEYCODE_COPY | 278 | |
KEYCODE_PASTE | 279 | |
KEYCODE_SYSTEM_NAVIGATION_UP | 280 | |
KEYCODE_SYSTEM_NAVIGATION_DOWN | 281 | |
KEYCODE_SYSTEM_NAVIGATION_LEFT | 282 | |
KEYCODE_SYSTEM_NAVIGATION_RIGHT | 283 |