children property
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();
}