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,
),
),
),
)
],
);
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()),