自定义主题无法正常工作.[扑]

Adr*_*ram 3 dart flutter

我为我的应用创建了以下主题:

ThemeData _buildDarkTheme() {
  final baseTheme = ThemeData(fontFamily: "Sunflower",);
  return baseTheme.copyWith(
      brightness: Brightness.dark,
      primaryColor: Colors.grey[800],
      accentColor: Colors.grey[850]);
}
Run Code Online (Sandbox Code Playgroud)

然后我将它应用到我的应用程序,如下所示:

class MyApp extends StatelessWidget {
  MyApp({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        theme: _buildDarkTheme(),
        home: new Scaffold(
          appBar: _buildAppBar(),
          body: new Container(
            color: Theme.of(context).accentColor,
            height: double.infinity,
            child: new ListView.builder(...
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试访问容器内部(或其他任何地方)的重点颜色而不是预期的Colors.grey [850]时,它默认为蓝色.此外,尝试使用自定义字体向日葵字体系列不起作用,但当我改为使用时

new Text("Hello World", style: new TextStyle(fontFamily: "Sunflower"))
Run Code Online (Sandbox Code Playgroud)

字体显示正确.

我是新手,因为任何解决这些问题的帮助都会受到欢迎.

rmt*_*zie 8

这与如何contextTheme.of工作有关.

从Theme类源代码:

  static ThemeData of(BuildContext context, { bool shadowThemeOnly = false }) {
    final _InheritedTheme inheritedTheme =
        context.inheritFromWidgetOfExactType(_InheritedTheme);
    if (shadowThemeOnly) {
      if (inheritedTheme == null || inheritedTheme.theme.isMaterialAppTheme)
        return null;
      return inheritedTheme.theme.data;
    }

    final ThemeData colorTheme = (inheritedTheme != null) ? inheritedTheme.theme.data : _kFallbackTheme;
    final MaterialLocalizations localizations = MaterialLocalizations.of(context);
    final TextTheme geometryTheme = localizations?.localTextGeometry ?? MaterialTextGeometry.englishLike;
    return ThemeData.localize(colorTheme, geometryTheme);
  }
Run Code Online (Sandbox Code Playgroud)

Theme.of(以及Navigator.of()...,. of()等),查看传递它们的上下文,然后向上遍历窗口小部件树,查找指定类型的窗口小部件.

现在,看看你的代码

Widget build(BuildContext context) {
    return new MaterialApp(
        theme: _buildDarkTheme(),
        home: new Scaffold(
          appBar: _buildAppBar(),
          body: new Container(
            color: Theme.of(context).accentColor,
Run Code Online (Sandbox Code Playgroud)

你可以看到context你传入Theme.of的实际上是你正在创建的主题之上的上下文.因此它将找不到您的主题并将恢复为默认值.这是因为窗口小部件树看起来有点像下图(忽略所有中间层,箭头指向您正在使用的上下文.

MyApp - context <--------
  MaterialApp
    Theme
      Scaffold
Run Code Online (Sandbox Code Playgroud)

有两种方法可以解决这个问题; 第一种是使用Builder类在具有主题下方的上下文的闭包内构建窗口小部件.这看起来像这样:

class MyApp extends StatelessWidget {
  MyApp({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        theme: _buildDarkTheme(),
    home: new Scaffold(
    appBar: _buildAppBar(),
    body: new Builder(builder: (context) => new Container(
      color: Theme.of(context).accentColor,
      height: double.infinity,
      child: new ListView.builder(...
    ))
Run Code Online (Sandbox Code Playgroud)

它会使一棵树看起来像这样:

MyApp - context
  MaterialApp
    Theme
      Scaffold
        Builder - context <---------
Run Code Online (Sandbox Code Playgroud)

另一个(首选)选项是将构建器的代码拆分为自己的类 - 无论是StatelessWidget-inherited类还是StatefulWidget和 - State对.