You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中ThemeData的ColorScheme使用问题:自定义主题属性不生效

Flutter明暗主题属性不生效问题解决

问题场景

配置了Flutter应用的明暗两种主题模式,在MaterialApp中指定了theme和darkTheme,但scaffoldBackgroundColor、AppBarTheme、InputDecorationTheme均未生效:

  • scaffoldBackgroundColor仍显示默认浅蓝色
  • AppBar中无法使用自定义ColorScheme的颜色
  • InputDecoration的fillColor和hintStyle颜色被忽略

相关核心代码如下:

MaterialApp配置

return MaterialApp(
  initialRoute: '/',
  routes: routesHandler,
  theme: lightThemeData(context),
  darkTheme: darkThemeData(context),
  debugShowCheckedModeBanner: false,
);

自定义ColorScheme

ColorScheme lightThemeColors(context) {
  return const ColorScheme(
    brightness: Brightness.light,
    primary: Color(0xFF202020),
    onPrimary: Color(0xFF505050),
    secondary: Color(0xFFBBBBBB),
    onSecondary: Color(0xFFEAEAEA),
    error: Color(0xFFF32424),
    onError: Color(0xFFF32424),
    background: Color(0xFFF1F2F3),
    onBackground: Color(0xFFFFFFFF),
    surface: Color(0xFF54B435),
    onSurface: Color(0xFF54B435),
  );
}

ColorScheme darkThemeColors(context) {
  return const ColorScheme(
    brightness: Brightness.dark,
    primary: Color(0xFFF1F2F3),
    onPrimary: Color(0xFFFFFFFF),
    secondary: Color(0xFFBBBBBB),
    onSecondary: Color(0xFFEAEAEA),
    error: Color(0xFFF32424),
    onError: Color(0xFFF32424),
    background: Color(0xFF202020),
    onBackground: Color(0xFF505050),
    surface: Color(0xFF54B435),
    onSurface: Color(0xFF54B435),
  );
}

原ThemeData实现(存在问题)

ThemeData lightThemeData(BuildContext context) {
  return ThemeData(
    scaffoldBackgroundColor: Theme.of(context).colorScheme.background,
    textTheme: textTheme(context),
    appBarTheme: appBarTheme(context),
    inputDecorationTheme: inputDecorationData(context),
    colorScheme: lightThemeColors(context),
  );
}

ThemeData darkThemeData(BuildContext context) {
  return ThemeData(
    scaffoldBackgroundColor: Theme.of(context).colorScheme.background,
    textTheme: textTheme(context),
    appBarTheme: appBarTheme(context),
    inputDecorationTheme: inputDecorationData(context),
    colorScheme: darkThemeColors(context),
  );
}

原AppBarTheme和InputDecorationTheme实现

AppBarTheme appBarTheme(context) {
  return AppBarTheme(
    backgroundColor: Theme.of(context).colorScheme.background,
    titleTextStyle: Theme.of(context).textTheme.headline5?.copyWith(color: Theme.of(context).colorScheme.primary),
  );
}
InputDecorationTheme inputDecorationData(context) {
  return InputDecorationTheme(
    filled: true,
    fillColor: Theme.of(context).colorScheme.onBackground,
    hintStyle: Theme.of(context).textTheme.bodyText1?.copyWith(color: Theme.of(context).colorScheme.onSecondary),
  );
}

问题原因

核心问题是构建ThemeData时,使用Theme.of(context)获取的是当前上下文的默认主题,而非正在创建的自定义ColorScheme。此时新的ThemeData还未被MaterialApp应用到上下文,所以所有依赖Theme.of(context)的属性都会读取默认主题值,导致自定义配置失效。

解决方案

修改ThemeData的构建逻辑,先创建自定义ColorScheme,然后直接基于这个Scheme来设置各个主题属性,不再通过Theme.of(context)获取:

1. 修改ThemeData函数

ThemeData lightThemeData(BuildContext context) {
  // 先创建自定义ColorScheme
  final colorScheme = lightThemeColors(context);
  // 基于自定义Scheme构建ThemeData
  return ThemeData(
    scaffoldBackgroundColor: colorScheme.background,
    textTheme: textTheme(context),
    appBarTheme: appBarTheme(colorScheme, context),
    inputDecorationTheme: inputDecorationData(colorScheme, context),
    colorScheme: colorScheme,
  );
}

ThemeData darkThemeData(BuildContext context) {
  final colorScheme = darkThemeColors(context);
  return ThemeData(
    scaffoldBackgroundColor: colorScheme.background,
    textTheme: textTheme(context),
    appBarTheme: appBarTheme(colorScheme, context),
    inputDecorationTheme: inputDecorationData(colorScheme, context),
    colorScheme: colorScheme,
  );
}

2. 修改AppBarTheme函数

接收自定义ColorScheme作为参数,直接使用它的颜色:

AppBarTheme appBarTheme(ColorScheme colorScheme, BuildContext context) {
  return AppBarTheme(
    backgroundColor: colorScheme.background,
    titleTextStyle: Theme.of(context).textTheme.headline5?.copyWith(color: colorScheme.primary),
  );
}

3. 修改InputDecorationTheme函数

同样接收自定义ColorScheme参数:

InputDecorationTheme inputDecorationData(ColorScheme colorScheme, BuildContext context) {
  return InputDecorationTheme(
    filled: true,
    fillColor: colorScheme.onBackground,
    hintStyle: Theme.of(context).textTheme.bodyText1?.copyWith(color: colorScheme.onSecondary),
  );
}

额外说明

如果textTheme也需要依赖自定义ColorScheme,同样可以把colorScheme参数传递过去,避免使用Theme.of(context)读取默认值。

内容的提问来源于stack exchange,提问作者anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:40:34