Home > Enterprise >  How to detect focus in children from a parent widget
How to detect focus in children from a parent widget

Time:02-18

In flutter,

  1. How can a parent widget know if a child among many children widgets has received focus? For example, Can we know if a child in a Row widget's children has received focus?

  2. Can I detect this focus before the child widget receives it?

CodePudding user response:

It actually depends on your take and which architecture you wanna follow. This snippet that I'm posting uses NotificationListener, a custom notification and a custom child widget. This might work for an application like a print or a callback, but you might need to change the architecture and use a state management tool to achieve greater things.

Parent Widget 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'),
          ),
        ),
      ),
    );
  }
}

Child Widget 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,
    );
  }
}

Custom Notification class:

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