Getting "The argument type 'Widget?' can't be assigned to the parameter type 'Widget'" error
A typical builder function would look like this:
Consumer<FooModel>(
builder: (context, model, child) {
return Text(model.foo());
}
)
However, if builder
is very expensive, it may be possible to move some of it out of the builder, and into a child
parameter:
Consumer<FooModel>(
builder: (context, model, child) {
return Column(children: [
Text(model.foo()),
VeryExpensiveWidget(), // this gets rebuilt every time FooModel updates
])
}
)
can become:
Consumer<FooModel>(
builder: (context, model, child) {
return Column(children: [
Text(model.foo()),
child, // this gets passed into the builder function
])
},
child: VeryExpensiveWidget(), // pass it as a child of the consumer
)
This effectively caches VeryExpensiveWidget
, building it once and then using that for all future calls to the builder.
The problem is that you may not pass a child
in. In the first example, we don't need the child parameter, and this is totally fine. However, it means that child
is now null
. Because this is allowed behaviour, child
must be a Widget?
In your case, you always pass in a child
parameter, so you can guarantee that the child
passed into builder
is non-null, so it is safe to use child!
to forcibly convert child
into a Widget
Your builder would then become:
builder: (_, cart, child) => Badge(child: child!, value: cart.itemCount.toString()),
Dadoh
Updated on November 28, 2022Comments
-
Dadoh over 1 year
I'm trying to build a Consumer but I'm getting this
The argument type 'Widget?' can't be assigned to the parameter type 'Widget'.
error underlined on the child inside the builder. Here's the code:
Consumer<Cart>( builder: (_, cart, ch) => Badge( child: ch, value: cart.itemCount.toString(), ), child: IconButton( icon: Icon( Icons.shopping_cart, ), onPressed: () {}, ), ),
Here's the Badge item it refers to:
Widget build(BuildContext context) { return Stack( alignment: Alignment.center, children: [ child, Positioned( right: 8, top: 8, child: Container( padding: EdgeInsets.all(2.0), // color: Theme.of(context).accentColor, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), color: Theme.of(context).accentColor, ), constraints: BoxConstraints( minWidth: 16, minHeight: 16, ), child: Text( value, textAlign: TextAlign.center, style: TextStyle( fontSize: 10, ), ), ), ) ], );