获取“参数类型‘Widget?’ 无法分配给参数类型“Widget””错误

Dad*_*doh 2 widget consumer dart flutter

我正在尝试建立一个消费者,但我得到了这个

参数类型“Widget?” 无法分配给参数类型“Widget”。

错误在生成器内的子项上加了下划线。这是代码:

Consumer<Cart>(
        builder: (_, cart, ch) => Badge(
              child: ch,
              value: cart.itemCount.toString(),
            ),
        child: IconButton(
          icon: Icon(
            Icons.shopping_cart,
          ),
          onPressed: () {},
        ),
      ),
Run Code Online (Sandbox Code Playgroud)

这是它引用的徽章项目:

  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,
          ),
        ),
      ),
    )
  ],
);
Run Code Online (Sandbox Code Playgroud)

cam*_*024 5

典型的构建器函数如下所示:

Consumer<FooModel>(
  builder: (context, model, child) {
    return Text(model.foo());
  }
)
Run Code Online (Sandbox Code Playgroud)

但是,如果builder非常昂贵,则可以将其中一些从构建器中移出并移入参数中child

Consumer<FooModel>(
  builder: (context, model, child) {
    return Column(children: [
      Text(model.foo()),
      VeryExpensiveWidget(),  // this gets rebuilt every time FooModel updates
    ])
  }
)
Run Code Online (Sandbox Code Playgroud)

可以变成:

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
)
Run Code Online (Sandbox Code Playgroud)

这可以有效地缓存VeryExpensiveWidget,构建一次,然后将其用于以后对构建器的所有调用。

问题是你可能不会传入一个childin。在第一个示例中,我们不需要 child 参数,这完全没问题。然而,这意味着就是child现在null。因为这是允许的行为,child所以必须是Widget?

在你的情况下,你总是传入一个child参数,所以你可以保证child传入的参数builder是非空的,所以使用child!强制转换child为一个是安全的Widget

然后你的建造者将变成:

builder: (_, cart, child) => Badge(child: child!, value: cart.itemCount.toString()),
Run Code Online (Sandbox Code Playgroud)