flutter 基础 —— Focus 组件的使用

Focus 组件

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: const <Widget>[
          MyCustomWidget(),
          MyCustomWidget(),
        ],
      ),
    );
  }
}

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

  @override
  State<MyCustomWidget> createState() => _MyCustomWidgetState();
}

class _MyCustomWidgetState extends State<MyCustomWidget> {
  Color _color = Colors.white;
  String _label = 'Unfocused';

  @override
  Widget build(BuildContext context) {
    return Focus(
      onFocusChange: (focused) {
        setState(() {
          _color = focused ? Colors.black26 : Colors.white;
          _label = focused ? 'Focused' : 'Unfocused';
        });
      },
      child: Center(
        child: Container(
          width: 300,
          height: 50,
          alignment: Alignment.center,
          color: _color,
          child: Text(_label),
        ),
      ),
    );
  }
}

注:可以按下 Tab 查看效果

Key Events ?

当 onKey 返回 KeyEventResult.handled, 则 key 事件不会传递给下一个节点

@override
Widget build(BuildContext context) {
  return Focus(
    onKey: (node, event) => KeyEventResult.handled,
    canRequestFocus: false,
    child: child,
  );
}

示例1:用于阻止文本输入(也可以使用 TextInputFormatter 解决)

@override
Widget build(BuildContext context) {
  return Focus(
    onKey: (node, event) {
      return (event.logicalKey == LogicalKeyboardKey.keyA)
          ? KeyEventResult.handled
          : KeyEventResult.ignored;
    },
    child: TextField(),
  );
}

示例2:绑定快捷键

class CallbackShortcuts extends StatelessWidget {
  const CallbackShortcuts({
    super.key,
    required this.bindings,
    required this.child,
  });

  final Map<ShortcutActivator, VoidCallback> bindings;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Focus(
      onKey: (node, event) {
        KeyEventResult result = KeyEventResult.ignored;
        // Activates all key bindings that match, returns handled if any handle it.
        for (final ShortcutActivator activator in bindings.keys) {
          if (activator.accepts(event, RawKeyboard.instance)) {
            bindings[activator]!.call();
            result = KeyEventResult.handled;
          }
        }
        return result;
      },
      child: child,
    );
  }
}

控制节点获得焦点

① skipTraversal: true

使用 Tab 该节点不会获得焦点,但使用 requestFocus 仍可获得焦点

② canRequestFocus: false

均无法获得焦点

③ descendantsAreFocusable: false

子节点不会获得焦点

FocusScope

对应 FocusScopeNode,用于分组

FocusableActionDetector

posted on 2022-09-20 11:25  Lemo_wd  阅读(489)  评论(0编辑  收藏  举报

导航