在 Flutter 中为 ThemeData 添加自定义 属性

Add custom property to ThemeData in Flutter

我需要根据主题更改 color 小部件。我有单独的 ThemeData 用于浅色和深色主题。现在是否可以将自定义 属性 添加到 ThemeData 以便我可以根据主题更改小部件的颜色并使用该自定义 属性?

遗憾的是,you simply can't - 考虑到他们的建议,Flutter 团队似乎对添加它不感兴趣。

我认为这是一个主要缺陷,因为我们无法从 Theme.of(context) 自动更新所有使用此 ThemeData.

Widget 中受益

虽然有些人可能会说您可以使用扩展来添加新属性,但实际上您不知道如何区分多个 ThemeData(除非您可以使用 Brightness 等属性,但是我认为这样做太老套了而且不可靠)。

另一种方法是创建另一个 InheritedWidget(就像他们在上述问题中所说的那样)来处理您的自定义主题属性。

编辑:似乎 new PR 已经引入了扩展 ThemeData 的可能性,但它还没有登陆 main 甚至稳定版。

我们可以通过 extension 功能扩展 ThemeData,而不是添加自定义 属性。例如,如果我们需要自定义颜色 属性,我们可以在 ColorScheme 上添加 extension 功能。 Color 依赖项现已移至 Themedata

// checking brightness to support dynamic themeing
extension CustomColorSchemeX on ColorScheme {
  Color get smallBoxColor1 =>
      brightness == Brightness.light ? Colors.blue : Colors.grey[400];
}

然后通过 Theme.of(context)...

访问 属性
                        Container(
                          decoration: BoxDecoration(
                            border: Border.all(
                                color: Theme.of(context)
                                    .colorScheme
                                    .smallBoxColor1),
                        ),

Flutter 最近推出 ThemeExtensions (thanks @guilherme-matuella for the PR link!)

您可以通过关注 Flutter 主存储库中的 examples 来了解如何使用该功能:

return MaterialApp(
  title: MyApp._title,
  theme: ThemeData.light().copyWith(
    extensions: <ThemeExtension<dynamic>>[
      const MyColors(
        brandColor: Color(0xFF1E88E5),
        danger: Color(0xFFE53935),
      ),
    ],
  ),
  darkTheme: ThemeData.dark().copyWith(
    extensions: <ThemeExtension<dynamic>>[
      const MyColors(
        brandColor: Color(0xFF90CAF9),
        danger: Color(0xFFEF9A9A),
      ),
    ],
  ),
  themeMode: isLightTheme ? ThemeMode.light : ThemeMode.dark,
  home: Home(
    isLightTheme: isLightTheme,
    toggleTheme: toggleTheme,
  ),
);

您稍后可以像这样在小部件中检索:
final MyColors myColors = Theme.of(context).extension<MyColors>()!;