children property

  1. @override
List<Widget> get children
override

The widgets below this widget in the tree.

If this list is going to be mutated, it is usually wise to put a Key on each of the child widgets, so that the framework can match old configurations to new configurations and maintain the underlying render objects.

Also, a Widget in Flutter is immutable, so directly modifying the children such as someMultiChildRenderObjectWidget.children.add(...) or as the example code below will result in incorrect behaviors. Whenever the children list is modified, a new list object should be provided.

// This code is incorrect.
class SomeWidgetState extends State<SomeWidget> {
  final List<Widget> _children = <Widget>[];

  void someHandler() {
    setState(() {
      _children.add(const ChildWidget());
    });
  }

  @override
  Widget build(BuildContext context) {
    // Reusing `List<Widget> _children` here is problematic.
    return Row(children: _children);
  }
}

The following code corrects the problem mentioned above.

class SomeWidgetState extends State<SomeWidget> {
  final List<Widget> _children = <Widget>[];

  void someHandler() {
    setState(() {
      // The key here allows Flutter to reuse the underlying render
      // objects even if the children list is recreated.
      _children.add(ChildWidget(key: UniqueKey()));
    });
  }

  @override
  Widget build(BuildContext context) {
    // Always create a new list of children as a Widget is immutable.
    return Row(children: _children.toList());
  }
}

Implementation

@override
List<Widget> get children {
  final elements = this.elements?.nonNulls ?? [];
  final result = Queue<Widget>();
  if (elements.isNotEmpty) {
    if (elements.length != 1) {
      final length = elements.length;
      for (var n = 0; n < length - 1; n++) {
        final e = elements.elementAt(n);
        result.add(e);
        if (this.divider != null) {
          result.add(this.divider!);
        }
      }
      final last = elements.last;
      result.add(last);
    } else {
      final first = elements.first;
      result.add(first);
    }
    if (this.firstIfNotEmpty != null) {
      result.addFirst(this.firstIfNotEmpty!);
    }
    if (this.lastIfNotEmpty != null) {
      result.addLast(this.lastIfNotEmpty!);
    }
  }

  return result.toList();
}