Приложению Flutter Android TV не удается выбрать с помощью D Pad

#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)),
                  ),