Flutter自定义ColorScheme.primary颜色不生效问题排查
问题原因
你遇到的核心问题是上下文作用域不匹配:在MaterialApp内部直接调用Theme.of(context)时,这个context来自当前build方法的父级上下文,并没有包含你刚定义的自定义主题配置,因此取到的是Flutter默认的Material主题颜色。而onSurface能生效,是因为MaterialApp会自动将主题中的该属性应用到全局文本样式,不需要通过Theme.of(context)手动获取。
解决方案
有两种简单的修复方式,任选其一即可:
方法1:用Builder包裹Scaffold
Builder组件会生成一个新的上下文,这个上下文会继承MaterialApp的主题配置,确保Theme.of(context)能拿到自定义颜色:
@override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( fontFamily: 'Poppins', colorScheme: const ColorScheme.light().copyWith( primary: const Color(0xFF2DBA4B), onPrimary: const Color(0xFFFFFFFF), secondary: const Color(0xFF2DBBA1), onSecondary: const Color(0xFFFFFFFF), surface: const Color(0xFFFEF7FF), surfaceDim: const Color(0xFFE1E1E1), onSurface: const Color(0xFF1D1B20), ), ), // 用Builder包裹Scaffold,获取包含自定义主题的上下文 home: Builder( builder: (context) { return Scaffold( bottomNavigationBar: Padding( padding: const EdgeInsets.only(bottom: 15), child: GNav( mainAxisAlignment: MainAxisAlignment.spaceEvenly, color: Theme.of(context).colorScheme.secondary, activeColor: Theme.of(context).colorScheme.onPrimary, tabBackgroundColor: Theme.of(context).colorScheme.primary, padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 17), gap: 7, onTabChange: (index) => navigateBottomBar(index), tabs: const [ GButton(icon: Icons.home, text: "Home"), GButton(icon: Icons.monetization_on, text: "Transactions"), GButton(icon: Icons.auto_graph, text: "Summary"), GButton(icon: Icons.settings, text: "Settings") ] ), ), body: SafeArea( child: Padding( padding: const EdgeInsets.all(10), child: pages[currentPage], ), ), ); }, ), debugShowCheckedModeBanner: false, ); }
方法2:将首页内容抽为独立组件
把Scaffold及其内部内容提取成单独的StatefulWidget/StatelessWidget,新组件的上下文会自动继承MaterialApp的主题:
// 抽离的首页组件 class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { int currentPage = 0; void navigateBottomBar(int index) { setState(() { currentPage = index; }); } @override Widget build(BuildContext context) { return Scaffold( bottomNavigationBar: Padding( padding: const EdgeInsets.only(bottom: 15), child: GNav( mainAxisAlignment: MainAxisAlignment.spaceEvenly, color: Theme.of(context).colorScheme.secondary, activeColor: Theme.of(context).colorScheme.onPrimary, tabBackgroundColor: Theme.of(context).colorScheme.primary, padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 17), gap: 7, onTabChange: (index) => navigateBottomBar(index), tabs: const [ GButton(icon: Icons.home, text: "Home"), GButton(icon: Icons.monetization_on, text: "Transactions"), GButton(icon: Icons.auto_graph, text: "Summary"), GButton(icon: Icons.settings, text: "Settings") ] ), ), body: SafeArea( child: Padding( padding: const EdgeInsets.all(10), child: pages[currentPage], ), ), ); } } // 原组件的build方法 @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( fontFamily: 'Poppins', colorScheme: const ColorScheme.light().copyWith( primary: const Color(0xFF2DBA4B), onPrimary: const Color(0xFFFFFFFF), secondary: const Color(0xFF2DBBA1), onSecondary: const Color(0xFFFFFFFF), surface: const Color(0xFFFEF7FF), surfaceDim: const Color(0xFFE1E1E1), onSurface: const Color(0xFF1D1B20), ), ), home: const HomePage(), debugShowCheckedModeBanner: false, ); }
内容的提问来源于stack exchange,提问作者Hrushikesh Vaidya
相关产品推荐
相关产品推荐

