Flutter自定义主题未生效:ElevatedButton背景色不更新
问题原因
- Context作用域错误:你在
Login组件的build方法里创建了新的MaterialApp,但调用Theme.of(context)时,这个context属于父级MyApp的MaterialApp,无法获取到当前刚定义的myTheme。 - 主题属性过时:Flutter新版本中,
primaryColor属于过时属性,ElevatedButton默认使用colorScheme.primary作为背景色,直接设置primaryColor可能不会被组件正确读取。
解决方法
方案一:将主题提升到根MaterialApp(推荐)
把自定义主题移到根组件MyApp的MaterialApp中,这样整个应用的context都能访问到统一的主题:
修改main.dart:
class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { final Color primaryColor = "#331b1b".toColor(); final ThemeData myTheme = ThemeData( colorScheme: ColorScheme.fromSeed( seedColor: primaryColor, primary: primaryColor, ), fontFamily: 'Roboto', ); return MaterialApp( theme: myTheme, home: const Login(), ); } } class Login extends StatelessWidget { const Login({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Align( alignment: Alignment.center, child: ElevatedButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const Home(), ), ); }, style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary, ), child: const Text('Ir a Home'), ), ), ], ), ); } }
方案二:使用Builder获取当前MaterialApp的context
如果必须在Login组件内创建MaterialApp,可以用Builder包裹按钮,让按钮的context属于当前MaterialApp:
修改Login组件:
class Login extends StatelessWidget { const Login({super.key}); @override Widget build(BuildContext context) { final Color primaryColor = "#331b1b".toColor(); final ThemeData myTheme = ThemeData( colorScheme: ColorScheme.fromSeed( seedColor: primaryColor, primary: primaryColor, ), fontFamily: 'Roboto', ); return MaterialApp( theme: myTheme, home: Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Align( alignment: Alignment.center, child: Builder( builder: (innerContext) { return ElevatedButton( onPressed: () { Navigator.of(innerContext).push( MaterialPageRoute( builder: (context) => const Home(), ), ); }, style: ElevatedButton.styleFrom( backgroundColor: Theme.of(innerContext).colorScheme.primary, ), child: const Text('Ir a Home'), ); }, ), ), ], ), ), ); } }
额外说明
- 优先使用
colorScheme来定义主题颜色,这是Flutter当前推荐的方式,能保证所有组件的颜色一致性。 - 避免在组件内部嵌套
MaterialApp,通常整个应用只需要一个根MaterialApp来管理主题、路由等全局配置。
内容的提问来源于stack exchange,提问作者Jniza
相关产品推荐
相关产品推荐

