flutter 焦点节点卡在最后一个节点

mgdq6dx1  于 2023-01-02  发布在  Flutter
关注(0)|答案(1)|浏览(125)

我有3个FocusNode,我想使用键盘或遥控器导航。
我已经设法做到了,但最后一个节点有问题。一旦它有了焦点,我就不能使用左箭头返回到前一个节点。返回对第二个节点有效,但对最后一个节点无效。
下面是我一直在尝试的代码:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  FocusNode? f1, f2, f3;

  void _onFocusChanged1() {
    bool f1Focus;
    setState(() => f1Focus = f1?.hasFocus ?? false);
  }

  void _onFocusChanged2() {
    bool f2Focus;
    setState(() => f2Focus = f2?.hasFocus ?? false);
  }

  void _onFocusChanged3() {
    bool f3Focus;
    setState(() => f3Focus = f3?.hasFocus ?? false);
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    if (f1 == null) {
      f1 = FocusNode();
      f2 = FocusNode();
      f3 = FocusNode();
      //Setting the 1st Focus to the appropriate widget
      //List<FocusNode> fnList= List.generate(3, (index) => FocusNode());
      f1?.addListener(_onFocusChanged1);
      f2?.addListener(_onFocusChanged2);
      f3?.addListener(_onFocusChanged3);
      f1?.requestFocus();
    }
  }

  @override
  void dispose() {
    f1!.dispose();
    f2!.dispose();
    f3!.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: RawKeyboardListener(
            focusNode: FocusNode(),
            onKey: (event) {
              if (event.runtimeType == RawKeyUpEvent) {
                if (event.logicalKey == LogicalKeyboardKey.arrowRight) {
                  _onFocusChanged1;
                  _onFocusChanged2;
                  _onFocusChanged3;
                } else if (event.logicalKey == LogicalKeyboardKey.arrowLeft) {
                  _onFocusChanged1;
                  _onFocusChanged2;
                  _onFocusChanged3;
                }
              }
            },
            child: Center(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Focus(
                      focusNode: f1,
                      child: Container(
                        padding: const EdgeInsets.all(16),
                        height: 100,
                        width: 100,
                        color: (f1?.hasPrimaryFocus ?? true)
                            ? Colors.red
                            : Colors.blue,
                      ),
                    ),
                    Focus(
                      focusNode: f2,
                      child: Container(
                        padding: const EdgeInsets.all(16),
                        height: 100,
                        width: 100,
                        color: (f2?.hasPrimaryFocus ?? true)
                            ? Colors.red
                            : Colors.blue,
                      ),
                    ),
                    Focus(
                      focusNode: f3,
                      child: Container(
                        padding: const EdgeInsets.all(16),
                        height: 100,
                        width: 100,
                        color: (f3?.hasPrimaryFocus ?? true)
                            ? Colors.red
                            : Colors.blue,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
zpjtge22

zpjtge221#

大部分代码都是一样的。我对代码做了一些修改,它可以做你想要的事情。逻辑很简单,如果按键被按下,它会检查哪个按键被按下,哪个节点有焦点,然后根据这个来改变焦点。另外,你检测按键的代码在我的系统上不起作用,所以我根据我的系统修改了它,但是你可以把它改回你想要的按键。
产品代码:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  FocusNode? f1, f2, f3;

  leftKeyPressed() { // check which node has focus
    if (f2!.hasFocus) {
      FocusScope.of(context).requestFocus(f1);
    } else if (f3!.hasFocus) {
      FocusScope.of(context).requestFocus(f2);
    }
  }

  rightKeyPressed() { // check which node has focus
    if (f1!.hasFocus) {
      FocusScope.of(context).requestFocus(f2);
    } else if (f2!.hasFocus) {
      FocusScope.of(context).requestFocus(f3);
    }
  }

  void _onFocusChanged1() {
    setState(() => f1?.hasFocus ?? false);
  }

  void _onFocusChanged2() {
    setState(() => f2?.hasFocus ?? false);
  }

  void _onFocusChanged3() {
    setState(() => f3?.hasFocus ?? false);
  }

  @override
  void initState() {
    super.initState();
    if (f1 == null) {
      f1 = FocusNode();
      f2 = FocusNode();
      f3 = FocusNode();
      f1?.addListener(_onFocusChanged1);
      f2?.addListener(_onFocusChanged2);
      f3?.addListener(_onFocusChanged3);
      f1?.requestFocus();
    }
  }

  @override
  void dispose() {
    f1!.dispose();
    f2!.dispose();
    f3!.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: RawKeyboardListener(
            focusNode: FocusNode(),
            onKey: (event) {
              if (event.runtimeType == RawKeyUpEvent) {
                if (event.logicalKey.keyLabel.toString() == "Numpad 4") { // check which key is has focus. "Numpad 4" is the left arrow key in my system.
                  leftKeyPressed();
                } else if (event.logicalKey.keyLabel.toString() == "Numpad 6") { //"Numpad 6" is the right arrow key in my system.
                  rightKeyPressed();
                }
              }
            },
            child: Center(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Focus(
                      focusNode: f1,
                      child: Container(
                        padding: const EdgeInsets.all(16),
                        height: 100,
                        width: 100,
                        color: (f1?.hasPrimaryFocus ?? true)
                            ? Colors.red
                            : Colors.blue,
                      ),
                    ),
                    Focus(
                      focusNode: f2,
                      child: Container(
                        padding: const EdgeInsets.all(16),
                        height: 100,
                        width: 100,
                        color: (f2?.hasPrimaryFocus ?? true)
                            ? Colors.red
                            : Colors.blue,
                      ),
                    ),
                    Focus(
                      focusNode: f3,
                      child: Container(
                        padding: const EdgeInsets.all(16),
                        height: 100,
                        width: 100,
                        color: (f3?.hasPrimaryFocus ?? true)
                            ? Colors.red
                            : Colors.blue,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

输出:-

相关问题