Flutter - 如何在ThemeData中使用自定义颜色和主题

6

我希望能够在ThemeData中使用自定义颜色和主题。我知道我可以在一个单独的文件中定义它们,然后导入并使用它们。但我希望这些颜色在切换深色和浅色主题时也能起作用。

目前,我有独立的深色和浅色主题,我要切换它们。有没有办法在深色和浅色主题中分别定义自定义颜色?

AppTheme.dart:

class AppTheme {
  AppTheme._();

  // Light Theme
  static final ThemeData lightTheme = ThemeData.light().copyWith(
    appBarTheme: AppBarTheme(
      color: Colors.grey[100],
      brightness: Brightness.light,
    ),
    scaffoldBackgroundColor: Colors.white,

    actionButtonColor: Colors.black, // Like this
  );

  // Dark Theme
  static final ThemeData darkTheme = ThemeData.dark().copyWith(
    appBarTheme: AppBarTheme(
      color: Colors.grey[850],
      brightness: Brightness.dark,
    ),
    scaffoldBackgroundColor: Colors.grey[900],

    actionButtonColor: Colors.red, // Like this
  );
}

App.dart

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Dashboard(),
      theme: AppTheme.lightTheme,
      darkTheme: AppTheme.darkTheme,
      debugShowCheckedModeBanner: false,
    );
  }
}
3个回答

6
我认为你在问题中已经得到了答案,你在代码示例中所做的是正确的,也是合法的。这里所说的“合法”,指的是代码将会正常工作并产生预期的结果,当然,除了actionButtonColor属性部分,因为该属性不属于ThemeData API。
或者,如果你想知道如何在你的主题数据中使用自定义的actionButtonColor属性,那么你不能这样做,因为它是一个预定义的小部件,用于与材料主题配合使用。这个actionButton应该只消耗主题中现有的属性。但如果你真的需要这样做,你可以使用Dart 2.7中的实验性扩展方法,例如:
extension MyColorScheme on ColorScheme {
  Color get actionButtonColor => const Colors.red;
}

ActionButtonComponent(
    color: Theme.of(context).colorScheme.actionButtonColor, 
);

然而,当使用扩展方法时,仍然无法为另一个ThemeData(如深色和浅色主题)设置不同的颜色方案。您可能需要查看此问题

希望这可以帮助您。


1
有没有其他替代方案:“但是,当使用扩展方法时,仍然无法为另一个ThemeData(如深色和浅色主题)设置不同的颜色方案。” - user3066829

4

你可以看一下ThemedData的扩展,我发现它非常有用且简单。

    extension LightThemeEx on ThemeData{
      Color get appSubTitleColor{
        return Color(0xFF5F6368);
      }
    }

您可以在其中创建自定义颜色;在您的小部件上实现方式非常相似:

      Theme.of(context).appSubTitleColor

希望它能帮助到你!

0

这将尝试通过使用AppTheme类本身来提供主题相关的自定义颜色,而不是扩展ThemeData来解决您的问题。

您需要:

  1. 一个静态getter,根据值获取颜色
  2. 一个在AppTheme类中存储当前主题状态的静态字段。

您可以使用布尔值作为静态字段,并在应用程序中从某个地方切换主题时更改其值。

修改后的AppTheme类如下:

class AppTheme {
  AppTheme._();

  // Light Theme
  static final ThemeData lightTheme = ThemeData.light().copyWith(
    appBarTheme: AppBarTheme(
      color: Colors.grey[100],
      brightness: Brightness.light,
    ),
    scaffoldBackgroundColor: Colors.white);
  

  // Dark Theme
  static final ThemeData darkTheme = ThemeData.dark().copyWith(
    appBarTheme: AppBarTheme(
      color: Colors.grey[850],
      brightness: Brightness.dark,
    ),
    scaffoldBackgroundColor: Colors.grey[900]);
  
  
  // Custom colors
  static bool _isThemeDark = false;

  static set isThemeDark(bool value) {_isThemeDark = value;}

  static get actionButtonColor => _isThemeDark
    ? Colors.green 
    : Colors.red;
}

您还可以使用提供者或任何状态管理解决方案,轻松更新主题和颜色。

class AppTheme with ChangeNotifier {
.
.
.
  set isThemeDark(bool value) {
  _isThemeDark = value; 
  notifyListner();
  }
}

使用示例:

void main(){
  AppTheme.isThemeDark=true;
  print(AppTheme.actionButtonColor);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接