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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:40:55