Flutter中Theme.of(context).colorScheme未显示预期颜色问题求助
Flutter ColorScheme 显示异常问题修复
问题根源
你在MainApp的build方法开头调用Theme.of(context).colorScheme时,当前context尚未绑定到你通过MaterialApp设置的自定义主题,获取到的是Flutter默认的蓝色系ColorScheme,导致所有使用该变量的颜色Tile都显示蓝色;而AppBar位于MaterialApp内部,其context能正确读取自定义主题,因此显示正常的绿色。
修复方案
有两种可靠的解决方式:
方式一:提前创建ColorScheme变量,直接复用
先手动创建基于绿色种子的ColorScheme,同时用于配置ThemeData和生成颜色Tile,无需依赖context获取主题:
import 'package:flutter/material.dart'; void main() { runApp(const MainApp()); } class MainApp extends StatelessWidget { const MainApp({super.key}); @override Widget build(BuildContext context) { // 提前生成自定义ColorScheme final ColorScheme cs = ColorScheme.fromSeed(seedColor: Colors.green); return MaterialApp( theme: ThemeData( colorScheme: cs, ), home: Scaffold( appBar: AppBar(title: const Center(child: Text('Colors'))), body: Center( child: ListView(children: [ MyColorTile(cs.primary, 'primary'), MyColorTile(cs.onPrimary, 'onPrimary'), MyColorTile(cs.primaryContainer, 'primaryContainer'), MyColorTile(cs.onPrimaryContainer, 'onPrimaryContainer'), MyColorTile(cs.secondary, 'secondary'), MyColorTile(cs.onSecondary, 'onSecondary'), MyColorTile(cs.secondaryContainer, 'secondaryContainer'), MyColorTile(cs.onSecondaryContainer, 'onSecondaryContainer'), MyColorTile(cs.tertiary, 'tertiary'), MyColorTile(cs.onTertiary, 'onTertiary'), MyColorTile(cs.tertiaryContainer, 'tertiaryContainer'), MyColorTile(cs.onTertiaryContainer, 'onTertiaryContainer'), MyColorTile(cs.error, 'error'), MyColorTile(cs.onError, 'onError'), MyColorTile(cs.errorContainer, 'errorContainer'), MyColorTile(cs.onErrorContainer, 'onErrorContainer'), MyColorTile(cs.outline, 'outline'), MyColorTile(cs.outlineVariant, 'outlineVariant'), MyColorTile(cs.background, 'background'), MyColorTile(cs.onBackground, 'onBackground'), MyColorTile(cs.surface, 'surface'), MyColorTile(cs.onSurface, 'onSurface'), MyColorTile(cs.surfaceVariant, 'surfaceVariant'), MyColorTile(cs.onSurfaceVariant, 'onSurfaceVariant'), MyColorTile(cs.inverseSurface, 'inverseSurface'), MyColorTile(cs.onInverseSurface, 'onInverseSurface'), MyColorTile(cs.inversePrimary, 'inversePrimary'), MyColorTile(cs.shadow, 'shadow'), MyColorTile(cs.scrim, 'scrim'), MyColorTile(cs.surfaceTint, 'surfaceTint'), ]), ), ), ); } } class MyColorTile extends StatelessWidget { final Color color; final String label; const MyColorTile(this.color, this.label, {super.key}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(3.0), child: ListTile( tileColor: color, // 优化:根据背景亮度自动切换文字颜色,提升可读性 title: Text(label, style: TextStyle(color: color.computeLuminance() > 0.5 ? Colors.black : Colors.white)), ), ); } }
方式二:将首页内容抽为独立组件,在组件内部获取主题
把展示颜色的页面抽成单独的Widget,利用其位于MaterialApp内部的context获取正确的主题:
import 'package:flutter/material.dart'; void main() { runApp(const MainApp()); } class MainApp extends StatelessWidget { const MainApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.green), ), home: const ColorDisplayPage(), ); } } class ColorDisplayPage extends StatelessWidget { const ColorDisplayPage({super.key}); @override Widget build(BuildContext context) { // 此处context已绑定自定义主题,可正确获取ColorScheme ColorScheme cs = Theme.of(context).colorScheme; return Scaffold( appBar: AppBar(title: const Center(child: Text('Colors'))), body: Center( child: ListView(children: [ MyColorTile(cs.primary, 'primary'), MyColorTile(cs.onPrimary, 'onPrimary'), // ... 其余颜色Tile代码与原代码一致 ]), ), ); } } class MyColorTile extends StatelessWidget { final Color color; final String label; const MyColorTile(this.color, this.label, {super.key}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(3.0), child: ListTile( tileColor: color, title: Text(label, style: TextStyle(color: color.computeLuminance() > 0.5 ? Colors.black : Colors.white)), ), ); } }
额外说明
两种方案都能解决问题,方式一更直接,无需依赖上下文;方式二更符合Flutter主题系统的使用习惯,适合后续主题动态切换的场景。另外优化了文字颜色逻辑,避免浅色背景下灰色文字看不清的问题。
内容的提问来源于stack exchange,提问作者Bob Enohp
相关产品推荐
相关产品推荐

