如何从父部件检测子部件的焦点

How to detect focus in children from a parent widget

扑腾中,

  1. 父控件如何知道众多子控件中的某个子控件是否获得了焦点?例如,我们能否知道 Row 小部件的子项中的子项是否已获得焦点?

  2. 我能否在子窗口小部件接收到此焦点之前检测到它?

这实际上取决于您的选择以及您想要遵循的架构。 我发布的这个片段使用了 NotificationListener、一个自定义通知和一个自定义子窗口小部件。这可能适用于打印或回调等应用程序,但您可能需要更改架构并使用状态管理工具来实现更大的目标。

父控件class:

class MyParentWidget extends StatelessWidget {
  const MyParentWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return NotificationListener<FocusNotification>(
      onNotification: (notification) {
        print("New widget focused: ${notification.childKey.toString()}");
        return true;
      },
      child: Row(
        children: List.generate(
          5,
          (index) => MyChildWidget(
            Key('widget-$index'),
          ),
        ),
      ),
    );
  }
}

子小部件 class:

class MyChildWidget extends StatefulWidget {
  const MyChildWidget(Key key) : super(key: key);

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

class _MyChildWidgetState extends State<MyChildWidget> {
  final node = FocusNode();

  @override
  initState() {
    node.addListener(() {
      if (node.hasFocus) {
        final notification = FocusNotification(widget.key!);
        notification.dispatch(context);
      }
    });
    super.initState();
  }

  @override
  dispose() {
    node.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      focusNode: node,
    );
  }
}

自定义通知class:

class FocusNotification extends Notification {
  const FocusNotification(this.childKey);
  final Key childKey;
}