Flutter:使用Consumer包裹IconButton后主题颜色失效的解决方法咨询
你的推测是正确的:Consumer的builder回调传入的context是Consumer内部的上下文,无法正确获取到上层配置的ThemeData,导致IconButton的颜色回退到默认蓝色。
解决方法很简单,在Consumer外部提前获取主题颜色,避免在builder回调中使用新的context去读取主题:
修改后的代码示例
class ProductItem extends StatelessWidget { const ProductItem({super.key}); @override Widget build(BuildContext context) { final product = Provider.of<Product>(context, listen: false); // 用当前组件的context提前获取自定义主题的secondary颜色 final secondaryColor = Theme.of(context).colorScheme.secondary; 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: secondaryColor, onPressed: () => product.toggleFavorite(), ), ), title: Text( product.title, textAlign: TextAlign.center, ), trailing: IconButton( icon: const Icon(Icons.shopping_cart), color: secondaryColor, onPressed: () {}, ), ), child: GestureDetector( onTap: () { Navigator.of(context).pushNamed( ProductDetailScreen.routeName, arguments: product.id, ); }, child: Image.network( product.imageUrl, fit: BoxFit.cover, ), ), ), ); } }
原理说明
ProductItem自身的context可以正常访问到MaterialApp中配置的ThemeData,提前获取颜色后在Consumer的builder中直接复用该变量,就能绕过Consumer上下文无法读取上层主题的问题,同时也能减少不必要的Theme监听重建。
内容的提问来源于stack exchange,提问作者Kulpas
相关产品推荐
相关产品推荐

