我正在使用 Flutter 开发 Android TV 应用程序。我可以运行该应用程序(目前是示例应用程序)。但我无法使用方向键选择按钮选择任何内容。
我发现我必须使用类似的东西才能实现这一目标
快捷方式(
shortcuts: {
LogicalKeySet(LogicalKeyboardKey.select):
const Intent(ActivateAction.key)
},
child: MaterialApp())
但是它在代码中给了我一个错误。我做错了什么?
如有任何帮助,我们将不胜感激。谢谢你。
添加此代码肯定对 Android TV OK/Select 按钮有帮助,并且可以扩展到其他映射。为 flutter 1.24-dev 构建并完美运行
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return Shortcuts(
shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
},
child: MaterialApp(
您可以使用 RawKeyboardListener 代替快捷方式,我使用了以下代码:
body: RawKeyboardListener(
autofocus: true,
focusNode: _focusNode,
onKey: _onKey,
child:Center())
void _onKey(RawKeyEvent e) {
controls();
if (e.runtimeType.toString() == 'RawKeyDownEvent') {
switch (e.logicalKey.debugName) {
case 'Media Play Pause':
case 'Select':
setState(() {
if (_videoViewController.value.isPlaying) {
_videoViewController.pause();
} else {
_videoViewController.play();
}
});
break;
}
}`
现在,如果您想要快进或快退,只需使用 RawKeyboardListener 即可 具体情况来处理。
您还可以使用方向键来执行此类操作。
可能这是一个迟到的答案。但我在电视应用程序上遇到了同样的问题。如果您的应用程序中没有文本字段,则上述步骤适用。如果您在应用程序中使用 textfeilds,则应该使用 FocasableActionDetector 小部件。 FocusableActionDetector 包括快捷方式、操作和焦点小部件。我处理事情的方式是,我创建了一个 FocusNode 列表,并将它们分配给页面中的可聚焦小部件。然后我将使用 FocusableActionDetector 包装所有可聚焦的小部件,并在 FocusableActionDetector 的操作参数中提供必要的按键逻辑。这是如何实现它的示例。
class LoginPage extends StatefulWidget {
LoginPage({Key? key}) : super(key: key);
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
GlobalKey<FormState> get loginFormKey => formKey ??= GlobalKey<FormState>();
int loginIndex = 0;
list<FocusNode> loginNodes = <FocusNode>[];
@override
void initState() {
for (var i = 0; i < 5; i++) {
loginNodes.add(FocusNode(debugLabel: 'loginNode $i'));
}
super.initState();
}
@override
void dispose() {
loginNodes.dispose();
super.dispose();
}
Map<ShortcutActivator, Intent> navigationIntents = {
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
LogicalKeySet(LogicalKeyboardKey.arrowRight): const RightbuttonIntent(),
LogicalKeySet(LogicalKeyboardKey.arrowLeft): const LeftbuttonIntent(),
LogicalKeySet(LogicalKeyboardKey.arrowUp): const UpbuttonIntent(),
LogicalKeySet(LogicalKeyboardKey.arrowDown): const DownbuttonIntent(),
LogicalKeySet(LogicalKeyboardKey.goBack): const BackButtonIntent()
//LogicalKeySet(LogicalKeyboardKey.back)
};
@override
Widget build(BuildContext context) {
return
FocusableActionDetector(
shortcuts: navigationIntents,
actions: <Type, Action<Intent>>{
DownbuttonIntent: CallbackAction<DownbuttonIntent>(
onInvoke: (intent) {
// if (loginIndex <= 0) loginIndex = 0;
if (loginIndex <= loginNodes.length - 1) {
loginIndex++;
log('index in downIntent if is $loginIndex');
FocusScope.of(context).requestFocus(loginNodes[loginIndex]);
} else if (loginIndex > loginNodes.length - 1) {
loginIndex = 4;
log('index in downIntent else is $loginIndex');
FocusScope.of(context).requestFocus(loginNodes[3]);
}
// log('index in downIntent is $loginIndex');
return KeyEventResult.ignored;
},
),
UpbuttonIntent: CallbackAction<UpbuttonIntent>(
onInvoke: (intent) {
if (loginIndex >= 0) {
loginIndex--;
FocusScope.of(context).requestFocus(loginNodes[loginIndex]);
log('index in upIntent else is $loginIndex');
} else if (loginIndex <= 0) {
loginIndex = 0;
log('index in upIntent if is $loginIndex');
FocusScope.of(context).requestFocus(loginNodes[0]);
loginNodes.refresh();
}
return KeyEventResult.ignored;
},
),
},
child: AuthScreenWrapper(
authForm: AuthForm(
formKey: loginFormKey,
title: 'login'.tr,
subtitle: 'login_to_continue'.tr,
formComponents: [
EmailInputField(emailFocus: loginNodes[0]),
PasswordInputField(passwordFocus: loginNodes[1]),
KeepMeForgotButtons(
rememberNode: loginNodes[2],
),
LoginButton(
btnNode: loginNodes[3],
),
],
),
),
);
}
}
我希望这对遇到与我相同问题的人有所帮助
我的解决方法是使用 Focus 小部件并使用它的 onKey 函数来模拟按键。
Focus(
onKey: (node, event) {
if (event.logicalKey == LogicalKeyboardKey.select && node.hasFocus) {
setState(() {
_debug = 'Pressed';
});
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
},
child: ElevatedButton(onPressed: () {}, child: Text(_debug)),
),
使用 FocusableActionDetector 而不是快捷方式
Scaffold(
body: FocusableActionDetector(
shortcuts: {
LogicalKeySet(LogicalKeyboardKey.select): ActivateIntent(),
},
actions: <Type, Action<Intent>>{
ActivateIntent: CallbackAction<ActivateIntent>(
onInvoke: (intent) {
// Do something when the select key is pressed.
},
),
},
child: Text('This text will be focused when the select key is pressed.'),
),
);
return Shortcuts(
shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
},
child: Actions(
actions: <Type, Action<Intent>>{
ActivateIntent: CallbackAction<ActivateIntent>(
onInvoke: (intent) {
// Only start the long-press timer if it is not already active
if (longPressTimer == null || !longPressTimer!.isActive) {
longPressTimer = Timer(Duration(milliseconds: 500), () {
// Execute an action after 500 milliseconds (adjust the duration as needed)
print("Select LongPress");
// Add your long-press action here
});
}
},
),
},
child: RawKeyboardListener(
focusNode: FocusNode(),
onKey: (event) {
if (event is RawKeyUpEvent) {
if (event.logicalKey == LogicalKeyboardKey.select) {
// Cancel the long-press timer and execute the action for short press
if (longPressTimer != null && longPressTimer!.isActive) {
longPressTimer!.cancel();
print("Select Short Press");
const ActivateIntent();
// Add your short-press action here
}
}
}
},
这样你就可以通过快捷键使用长按和短按
使用上面朋友的方法,这样我们就可以在电视上使用方向键长按和点击功能。只需在 main.dart 中使用它即可
class MyApp extends StatelessWidget with RouteAware {
final String? filePath;
const MyApp({Key? key, this.filePath}) : super(key: key);
@override
Widget build(BuildContext context) {
return Shortcuts(
shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
},
并且在你长按这个的焦点
onKey: (node, event) {
if (event.logicalKey == LogicalKeyboardKey.select &&
node.hasFocus) {
if (event is RawKeyDownEvent) {
_longPressTimer =
Timer(Duration(milliseconds: 500), () {
_isLongPressDetected = true;
print("Long press detected");
// Implemente a ação que deseja realizar para o long press
});
} else if (event is RawKeyUpEvent) {
_longPressTimer?.cancel();
if (!_isLongPressDetected) {
print("Short press detected");
// Implemente a ação que deseja realizar para o short press
}
_isLongPressDetected =
false; // Reseta a variável de controle para o próximo pressionamento
return KeyEventResult.handled;
}
}
return KeyEventResult.ignored;
},
现在您可以使用具有长按和按下功能的方向键