#android #flutter #flutter-layout #android-tv #d-pad
#Android #flutter #flutter-layout #android-tv #d-pad
Вопрос:
Я разрабатываю приложение для Android TV с использованием Flutter. Я могу запустить приложение (пока пример приложения). Но я ничего не могу выбрать с помощью кнопки выбора d pad.
Я обнаружил, что для достижения этого мне нужно использовать что-то вроде этого
Ярлыки (
shortcuts: {
LogicalKeySet(LogicalKeyboardKey.select):
const Intent(ActivateAction.key)
},
child: MaterialApp())
Но это выдает мне ошибку в коде. Что я делаю не так?
Приветствуется любая помощь. Спасибо.
Комментарии:
1. В коде Java кнопка называется не «Выбрать», а «по центру». Есть ли у вас постоянная центральная клавиша во Flutter?
Ответ №1:
Добавление этого кода определенно помогает для кнопки 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(
Комментарии:
1. не работает flutter 2.5.
Ответ №2:
Вместо ярлыков может быть 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 с
конкретный случай, чтобы справиться с этим.
Вы также можете использовать свои клавиши D-PAD для выполнения такого действия.
Комментарии:
1. это должно быть правильно!
Ответ №3:
Возможно, это поздний ответ. Но я столкнулся с той же проблемой в телевизионном приложении. Вышеупомянутые шаги применимы, если в вашем приложении нет текстовых полей. Если вы используете текстовые поля в своем приложении, вам следует использовать виджет FocasableActionDetector. FocusableActionDetector включает ярлыки, действия и виджеты фокусировки. Я поступил следующим образом: создал список фокусных узлов и назначил их фокусируемым виджетам на странице. тогда я бы обернул все фокусируемые виджеты с помощью 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],
),
],
),
),
);
}
}
Я надеюсь, что это поможет кому-то, кто столкнулся с той же проблемой, что и у меня
Ответ №4:
Моим решением было использовать виджет фокусировки и использовать его функцию OnKey для имитации нажатия клавиши.
Focus(
onKey: (node, event) {
if (event.logicalKey == LogicalKeyboardKey.select amp;amp; node.hasFocus) {
setState(() {
_debug = 'Pressed';
});
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
},
child: ElevatedButton(onPressed: () {}, child: Text(_debug)),
),