Flutter的colorScheme在用Consumer包装小部件后恢复为默认值。

huangapple go评论67阅读模式
英文:

Flutter colorScheme reverting to default after wrapping widget with Consumer

问题

在使用Consumer包装IconButton时,IconButton的颜色从我的主题更改为默认的蓝色。我认为这是因为传递给builder的上下文不同。使用Consumer以保留主题的正确方式是什么?

这里是具有Consumer的类:

class ProductItem extends StatelessWidget {
  const ProductItem({super.key});

  @override
  Widget build(BuildContext context) {
    final product = Provider.of<Product>(context, listen: false);

    return ClipRRect(
      borderRadius: BorderRadius.circular(10),
      child: GridTile(
        footer: GridTileBar(
          backgroundColor: Colors.black87,
          leading: Consumer<Product>(
            builder: (context, value, _) => IconButton(
              icon: Icon(
                value.isFavorite ? Icons.favorite : Icons.favorite_border,
              ),
              color: Theme.of(context).colorScheme.secondary,
              onPressed: () => product.toggleFavorite(),
            ),
          ),
          title: Text(
            product.title,
            textAlign: TextAlign.center,
          ),
          trailing: IconButton(
            icon: const Icon(Icons.shopping_cart),
            color: Theme.of(context).colorScheme.secondary,
            onPressed: () {},
          ),
        ),
        child: GestureDetector(
          onTap: () {
            Navigator.of(context).pushNamed(
              ProductDetailScreen.routeName,
              arguments: product.id,
            );
          },
          child: Image.network(
            product.imageUrl,
            fit: BoxFit.cover,
          ),
        ),
      ),
    );
  }
}

这是主题:

theme: ThemeData(
  colorScheme: ColorScheme.fromSwatch(
    primarySwatch: Colors.purple,
    accentColor: Colors.deepOrange,
  ),
  fontFamily: 'Lato',
),
英文:

while taking a course on Flutter I ran into and issue where wrapping the IconButton with a consumer causes it to change colors from my theme to default blue. I assume it's because the context passed into the builder is different. What's the correct way of using the Consumer to retain the theme?

Here's the class with the Consumer:

class ProductItem extends StatelessWidget {
  const ProductItem({super.key});

  @override
  Widget build(BuildContext context) {
    final product = Provider.of&lt;Product&gt;(context, listen: false);

    return ClipRRect(
      borderRadius: BorderRadius.circular(10),
      child: GridTile(
        footer: GridTileBar(
          backgroundColor: Colors.black87,
          leading: Consumer&lt;Product&gt;(
            builder: (context, value, _) =&gt; IconButton(
              icon: Icon(
                value.isFavorite ? Icons.favorite : Icons.favorite_border,
              ),
              color: Theme.of(context).colorScheme.secondary,
              onPressed: () =&gt; product.toggleFavorite(),
            ),
          ),
          title: Text(
            product.title,
            textAlign: TextAlign.center,
          ),
          trailing: IconButton(
            icon: const Icon(Icons.shopping_cart),
            color: Theme.of(context).colorScheme.secondary,
            onPressed: () {},
          ),
        ),
        child: GestureDetector(
          onTap: () {
            Navigator.of(context).pushNamed(
              ProductDetailScreen.routeName,
              arguments: product.id,
            );
          },
          child: Image.network(
            product.imageUrl,
            fit: BoxFit.cover,
          ),
        ),
      ),
    );
  }
}

and here is the theme:

theme: ThemeData(
          colorScheme: ColorScheme.fromSwatch(
            primarySwatch: Colors.purple,
            accentColor: Colors.deepOrange,
          ),
          fontFamily: &#39;Lato&#39;,
        ),

答案1

得分: 1

好的,以下是翻译好的部分:

问题已经被我自己解决了。问题在于作为参数传递给Consumer构建方法的上下文与传递给ProductItem的构建方法中的上下文不同,并在Consumer的范围内覆盖了它。

要修复它,你只需要将传递给构建函数的变量重命名(例如,将其替换为下划线):

leading: Consumer<Product>(
  //还必须将child参数更改为两个下划线以避免名称冲突
  builder: (_, value, __) => IconButton(
    icon: Icon(
      value.isFavorite ? Icons.favorite : Icons.favorite_border,
    ),
    color: Theme.of(context).colorScheme.secondary,
    onPressed: () => product.toggleFavorite(),
  ),
),
英文:

Okay, I figured it out myself. The issue is that the context passed as an argument inside the Consumer builder method is a different context than the passed into the build method of ProductItem and overrides it inside the scope of Consumer.

To fix it all you need to do is rename the variable passed into the builder function (e.g. replace it with an underscore)

leading: Consumer&lt;Product&gt;(
  //also had to change child argument to two underscores to avoid name conflict
  builder: (_, value, __) =&gt; IconButton(
    icon: Icon(
      value.isFavorite ? Icons.favorite : Icons.favorite_border,
    ),
    color: Theme.of(context).colorScheme.secondary,
    onPressed: () =&gt; product.toggleFavorite(),
  ),
),

huangapple
  • 本文由 发表于 2023年1月8日 22:38:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75048625.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定