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

Flutter深色主题文本颜色不生效,如何用单个TextTheme+GetX适配双主题?

问题根源

你当前的问题出在静态TextTheme初始化时就固定了颜色值——MyTextTheme.myTextTheme是静态变量,第一次加载时就根据当时的Get.isDarkMode状态确定了颜色,后续切换主题时这个变量不会重新生成,所以深色模式下文本颜色还是初始的浅色值(或相反),自然不生效。

解决方案

以下是几种无需维护两个独立TextTheme类的实现方式,按实用性排序:


方案一:将TextTheme改为动态生成的方法(最直接)

把静态变量改成静态方法,每次获取时都根据当前Get.isDarkMode状态重新构建TextTheme,确保亮色/深色主题调用时拿到对应颜色的样式:

修改MyTextTheme类:

class MyTextTheme {
  static const String fontFamily = 'Vazir';

  // 改成静态方法,每次调用都生成新的TextTheme
  static TextTheme getTextTheme() {
    return TextTheme(
      titleLarge: TextStyle(
        fontSize: 25,
        fontWeight: FontWeight.w700,
        color: Get.isDarkMode
            ? const Color.fromARGB(255, 255, 242, 231)
            : const Color.fromARGB(255, 137, 116, 253),
      ),
      // 其他文本样式同理
    );
  }
}

更新主题代码,调用方法替代静态变量:

static final lightTheme = ThemeData(
  // ...其他配置(buttonTheme、primaryColor等)
  textTheme: MyTextTheme.getTextTheme(),
);

static final darkTheme = ThemeData(
  // ...其他配置(elevatedButtonTheme、colorScheme等)
  textTheme: MyTextTheme.getTextTheme(),
);

注意:切换主题后需要确保页面重建(比如用Get.forceAppUpdate()或依赖主题变化的Obx),这样会重新调用getTextTheme()获取最新颜色。


方案二:贴合GetX生态的响应式实现

如果希望主题切换时文本样式自动更新,无需手动重建页面,可以结合GetX的响应式变量:

  1. 在主题管理Controller中添加响应式TextTheme:
class ThemeController extends GetxController {
  final RxBool isDarkMode = false.obs;

  // 响应式TextTheme,随isDarkMode变化自动更新
  final Rx<TextTheme> currentTextTheme = Rx<TextTheme>(_buildInitialTextTheme());

  void toggleTheme() {
    isDarkMode.value = !isDarkMode.value;
    // 更新全局主题
    Get.changeTheme(isDarkMode.value ? AppThemes.darkTheme : AppThemes.lightTheme);
    // 同步更新TextTheme
    currentTextTheme.value = _buildTextTheme(isDarkMode.value);
  }

  static TextTheme _buildInitialTextTheme() {
    return TextTheme(
      titleLarge: TextStyle(
        fontSize: 25,
        fontWeight: FontWeight.w700,
        color: Get.isDarkMode
            ? const Color.fromARGB(255, 255, 242, 231)
            : const Color.fromARGB(255, 137, 116, 253),
      ),
    );
  }

  static TextTheme _buildTextTheme(bool isDark) {
    return TextTheme(
      titleLarge: TextStyle(
        fontSize: 25,
        fontWeight: FontWeight.w700,
        color: isDark
            ? const Color.fromARGB(255, 255, 242, 231)
            : const Color.fromARGB(255, 137, 116, 253),
      ),
      // 其他样式
    );
  }
}
  1. 页面中通过Obx监听并使用:
final themeController = Get.find<ThemeController>();

// 在Widget中使用响应式样式
Obx(() => Text(
  "示例标题",
  style: themeController.currentTextTheme.value.titleLarge,
));

方案三:关联Material ColorScheme(符合设计规范)

不硬编码颜色,而是通过ThemeData的colorScheme关联文本颜色,亮色/深色主题的colorScheme不同,文本颜色自动适配:

修改MyTextTheme,接收ColorScheme参数:

class MyTextTheme {
  static const String fontFamily = 'Vazir';

  // 根据传入的ColorScheme生成对应样式
  static TextTheme getTextTheme(ColorScheme colorScheme) {
    return TextTheme(
      titleLarge: TextStyle(
        fontSize: 25,
        fontWeight: FontWeight.w700,
        color: colorScheme.onSurface, // 关联colorScheme的对应颜色
      ),
      // 其他文本样式可关联colorScheme.onBackground、colorScheme.onPrimary等
    );
  }
}

更新主题代码,配置colorScheme并传入:

static final lightTheme = ThemeData(
  colorScheme: ColorScheme.fromSwatch(
    backgroundColor: Colors.white,
    onSurface: const Color.fromARGB(255, 137, 116, 253), // 浅色主题文本颜色
  ),
  // ...其他配置
  textTheme: MyTextTheme.getTextTheme(lightTheme.colorScheme),
);

static final darkTheme = ThemeData(
  colorScheme: ColorScheme.dark().copyWith(
    onSurface: const Color.fromARGB(255, 255, 242, 231), // 深色主题文本颜色
  ),
  // ...其他配置
  textTheme: MyTextTheme.getTextTheme(darkTheme.colorScheme),
);

这种方式遵循Material设计的颜色系统,后续修改主题颜色只需调整colorScheme,无需改动TextTheme。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:29:54