英文:
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<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,
),
),
),
);
}
}
and here is the theme:
theme: ThemeData(
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
),
fontFamily: 'Lato',
),
答案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<Product>(
//also had to change child argument to two underscores to avoid name conflict
builder: (_, value, __) => IconButton(
icon: Icon(
value.isFavorite ? Icons.favorite : Icons.favorite_border,
),
color: Theme.of(context).colorScheme.secondary,
onPressed: () => product.toggleFavorite(),
),
),
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论