flutter开发电视TV应用

一、前言:正常app的应用在电视剧上是触发不了事件的,所以今天的主角出现了=》KeyboardListener

1、用KeyboardListener可以监听键盘的事件,在onKeyEvent中对各案件做判断。

2、我这里主要是实现各button按钮的点击(可以判断是哪个button点击)

二、实现方式

1、可以在KeyboardListener的onKeyEvent方法中通过如下方法获取focusScope里面的参数:

String? debugLabel =FocusScope.of(context).focusedChild?.debugLabel;
2、可以在focus中的回调函数onkey或onKeyEvent中判断事件
onKeyEvent: (node, event) {
             
              if (event.logicalKey.keyId == 4294968588 ||
                  event.logicalKey == LogicalKeyboardKey.select) {
                //处理自己的逻辑
                debugPrint("2菜单点击:" + "a" + i.toString());
                updateTextFirst(
                    xx + "_" + event.logicalKey.keyLabel.toString());
                Scrollable.ensureVisible(
                    globalKeys[i].currentContext as BuildContext);
              } else {
                updateTextFirst(event.logicalKey.keyId.toString() +
                    "_" +
                    event.logicalKey.keyLabel.toString());
              }
              return KeyEventResult.ignored;
            },

三、完整代码

import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:bruno/bruno.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';

class Aoc extends StatelessWidget {
  const Aoc({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      // theme: ThemeData(
      //   primarySwatch: Colors.blue,
      // ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
    // return Shortcuts(
    //   shortcuts: <LogicalKeySet, Intent>{
    //     LogicalKeySet(LogicalKeyboardKey.enter): const ActivateIntent(),
    //     LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent()
    //   },
    //   child: MaterialApp(
    //     title: 'Flutter Demo',
    //     theme: ThemeData(
    //       primarySwatch: Colors.blue,
    //     ),
    //     home: const MyHomePage(title: 'Flutter Demo Home Page'),
    //   ),
    // );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  GlobalKey key1 = GlobalKey();
  GlobalKey key2 = GlobalKey();
  GlobalKey key3 = GlobalKey();

  List<GlobalKey> globalKeys = [];

  String buttonTwo = "弹窗二";
  String buttonThree = "弹窗三";
  String buttonFirst = "四";

  void updateText(String newText) {
    setState(() {
      buttonTwo = newText;
    });
  }

  void updateTextThree(String newText) {
    setState(() {
      buttonThree = newText;
    });
  }

  void updateTextFirst(String newText) {
    setState(() {
      buttonFirst = newText;
    });
  }

  Widget build(BuildContext context) {
    var width = MediaQuery.of(context).size.width - 20;
    // TODO: implement build
    // bruno官方组件介绍
    // https://bruno.ke.com/page/v3.2.0/widgets/brn-enhance-operation-dialog
    BrnEnhanceOperationDialog enhanceOperationDialog =
        new BrnEnhanceOperationDialog(
      iconType: BrnDialogConstants.iconAlert,
      context: context,
      titleText: "已经跳转页面",
      descText: "这里是文案这里是文案这里是文案这里是文案这里是文案这里是文案这里是文案这里是文案",
      mainButtonText: "我知道了",
      onSecondaryButtonClick: () {
        print("主要按钮");
      },
    );
    FocusNode focusNode0 = FocusNode();
    globalKeys.add(key1);
    globalKeys.add(key2);
    globalKeys.add(key3);
    // 修改根节点的组件类型为Scaffold或者Material,解决text下划线的问题
    return Material(
      child: Stack(
        children: <Widget>[
          Container(
            child: SingleChildScrollView(
              child: Stack(
                children: [
                  Column(
                    children: getImagesList(),
                    // children: [
                    //   Container(
                    //     // height:600,
                    //     decoration: BoxDecoration(
                    //         borderRadius: BorderRadius.circular(10)),
                    //     clipBehavior: Clip.hardEdge,
                    //     child: Image.asset(
                    //       "assets/zt_images_first/company_first.jpg",
                    //       width: MediaQuery.of(context).size.width,
                    //     ),
                    //     key: key1,
                    //   ),
                    //   Container(
                    //     height: 500,
                    //     key: key2,
                    //     color: Colors.green,
                    //   ),
                    //   Container(
                    //     height: 500,
                    //     key: key3,
                    //     color: Colors.blue,
                    //   )
                    // ],
                  )
                ],
              ),
            ),
          ),
          Positioned(
              bottom: 60,
              right: 10,
              child: Container(
                height: 410,
                decoration: BoxDecoration(),
                child: KeyboardListener(
                  focusNode: FocusNode(),
                  onKeyEvent: (value) {
                    if (value is KeyDownEvent) {
                      // if (value.logicalKey == LogicalKeyboardKey.arrowLeft) {
                      //   //debugPrint("左");
                      //   FocusScope.of(context)
                      //       .focusInDirection(TraversalDirection.left);
                      // } else if (value.logicalKey == LogicalKeyboardKey.arrowRight) {
                      //   //debugPrint("右");
                      //   FocusScope.of(context)
                      //       .focusInDirection(TraversalDirection.right);
                      // }
                      // else
                      if (value.logicalKey == LogicalKeyboardKey.arrowUp) {
                        // print("sssssssss"+LogicalKeyboardKey.arrowUp.toString());
                        //debugPrint("上");
                        FocusScope.of(context)
                            .focusInDirection(TraversalDirection.up);
                      } else if (value.logicalKey ==
                          LogicalKeyboardKey.arrowDown) {
                        // print("xxxxxxxxx"+LogicalKeyboardKey.arrowDown.toString());
                        //debugPrint("下");
                        FocusScope.of(context)
                            .focusInDirection(TraversalDirection.down);
                      }
                      if (value.logicalKey == LogicalKeyboardKey.enter) {
                        String? debugLabel =
                            FocusScope.of(context).focusedChild?.debugLabel;
                        print("key=====enterxx===========" + debugLabel!);
                        updateTextThree(debugLabel!);
                      }
                    }
                  },
                  child: buildRightMenu(enhanceOperationDialog),
                ),
              ))
        ],
      ),
    );
  }

  List<Widget> getImagesList() {
    List<Widget> widgetList = [];
    List<String> imagesList = [];
    imagesList.add("assets/zt_images_first/company_first.jpg");
    imagesList.add("assets/zt_images_first/company_two.png");
    imagesList.add("assets/zt_images_first/company_three.png");
    for (int i = 0; i < imagesList.length; i++) {
      widgetList.add(Container(
        // height:600,
        decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)),
        clipBehavior: Clip.hardEdge,
        child: Image.asset(
          imagesList[i],
          width: MediaQuery.of(context).size.width,
          fit:BoxFit.cover
        ),
        key: globalKeys[i],
      ));
    }

    return widgetList;
  }

  List<Widget> getButtonList(BrnEnhanceOperationDialog enhanceOperationDialog) {
    List<Widget> getButtonList = [];
    for (int i = 0; i < 3; i++) {
      String xx = "axx" + i.toString();
      String param = "abbbxx" + i.toString();
      getButtonList.add(FocusScope(
          debugLabel: param,
          child: Focus(
            debugLabel: xx,
            onKey: (node, event) {
              return KeyEventResult.ignored;
            },
            onKeyEvent: (node, event) {
              // if (event is KeyDownEvent &&
              //     event.logicalKey == LogicalKeyboardKey.enter) {
              //   debugPrint("1菜单点击:" + "a" + i.toString());
              //   updateTextFirst(xx);
              //   Scrollable.ensureVisible(
              //       globalKeys[i].currentContext as BuildContext);
              // } else
              if (event.logicalKey.keyId == 4294968588 ||
                  event.logicalKey == LogicalKeyboardKey.select) {
                debugPrint("2菜单点击:" + "a" + i.toString());
                updateTextFirst(
                    xx + "_" + event.logicalKey.keyLabel.toString());
                Scrollable.ensureVisible(
                    globalKeys[i].currentContext as BuildContext);
              } else {
                updateTextFirst(event.logicalKey.keyId.toString() +
                    "_" +
                    event.logicalKey.keyLabel.toString());
              }
              return KeyEventResult.ignored;
            },
            child: Builder(
              builder: (context) {
                FocusNode focusNode = Focus.of(context);
                return Container(
                  decoration: BoxDecoration(
                    // border: Border.all(color: Colors.white),
                    color: focusNode.hasFocus
                        ? Colors.orangeAccent.shade700
                        : Colors.blue.shade500,
                    borderRadius: BorderRadius.circular(6),
                  ),
                  margin: EdgeInsets.only(top: 15),
                  width: 60,
                  height: 25,
                  child: Center(
                    child: InkWell(
                      onTap: () {
                        Scrollable.ensureVisible(
                            globalKeys[i].currentContext as BuildContext);
                      },
                      child: Text(
                        (i + 1).toString(),
                        style: TextStyle(color: Colors.white),
                      ),
                    ),
                  ),
                );
                // return ElevatedButton(
                //     style: ButtonStyle(
                //       overlayColor: MaterialStateProperty.all(Color(0xff31C27C)),
                //       // 高亮色
                //       shadowColor: MaterialStateProperty.all(Colors.red),
                //       // 阴影颜色
                //       textStyle: MaterialStateProperty.all(TextStyle(fontSize: 16)),
                //       // 字体
                //       //高亮:字体颜色
                //       side: MaterialStateProperty.all(BorderSide(width: 1, color: Color(0xffffffff))),
                //     ),
                //     onPressed: () {
                //   // enhanceOperationDialog.show();
                //   // updateTextThree("113");
                //   Scrollable.ensureVisible(
                //       globalKeys[i].currentContext as BuildContext);
                // }, child: Text((i+1).toString()));
              },
            ),
          )));
    }
    // getButtonList.add(ElevatedButton(onPressed: () {}, child: Text(buttonTwo)));
    //
    // getButtonList
    //     .add(ElevatedButton(onPressed: () {}, child: Text(buttonThree)));
    // getButtonList
    //     .add(ElevatedButton(onPressed: () {}, child: Text(buttonFirst)));
    return getButtonList;
  }

  //动态遍历
  // getButtonContro(BrnEnhanceOperationDialog enhanceOperationDialog) {
  //   return Row(children: getButtonList(enhanceOperationDialog));
  //   // return Container(child: getButtonInfo(enhanceOperationDialog),);
  // }

  Widget buildButton() {
    return Focus(
      debugLabel: "nn",
      child: Builder(
        builder: (context) {
          FocusNode focusNode = Focus.of(context);
          return Container(
            child: Text("sssssssssss"),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.white),
              color: focusNode.hasFocus ? Colors.amber : Colors.black,
            ),
            width: 80,
            height: 80,
          );
        },
      ),
    );
  }

  /// 右侧菜单 3 个 竖向按钮
  Widget buildRightMenu(BrnEnhanceOperationDialog enhanceOperationDialog) {
    return Column(
      children: getButtonList(enhanceOperationDialog),
    );
    // return FocusScope(
    //   debugLabel: "a",
    //   onFocusChange: (value) {
    //     debugPrint("右侧部菜单区域焦点:" + value.toString());
    //   },
    //   child: Column(
    //     children: getButtonList(enhanceOperationDialog),
    //   ),
    // );
  }
}

//电视点击事件
void _incrementCounter(ActivateIntent intent) {
  print("-----");
}

class ActivateIntent extends Intent {
  const ActivateIntent();
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值