简体   繁体   English

如何设置Flutter中一个小部件下所有文本小部件的颜色?

[英]How to set color of all Text widgets under a widget in Flutter?

According to this answer , all I have to do is to wrap a widget with Theme and provide ThemeData .根据这个答案,我所要做的就是用Theme包装一个小部件并提供ThemeData I return a widget from build method as below:我从build方法返回一个小部件,如下所示:

    Theme( // wrapping `Card` widget with a theme
      data: Theme.of(context).copyWith( // extend main theme
        textTheme: Theme.of(context).textTheme.copyWith( // extend main text theme
              subtitle1: TextStyle(
                color: Colors.white, // subtitle text color to white
              ),
              caption: TextStyle(
                color: Colors.white, // caption text color to white
              ),
            ),
      ),
      child: Card( // card widget as a child of theme
        // ... other stuff ...
        child: Container(
            margin: _margin,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Text(
                  profile.alias,
                  style: Theme.of(context).textTheme.subtitle1, // set text style to subtitle1
                ),
                Expanded(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.end,
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      Text(
                        'Joined ${timeago.format(profile.dateJoined)}',
                        style: Theme.of(context).textTheme.caption, // set text style to subtitle2
                        textAlign: TextAlign.right,
                      ),
                      Text(
                        'Has ${profile.stats.subscriberCount == null ? 0 : profile.stats.subscriberCount} subscribers',
                        style: Theme.of(context).textTheme.caption, // set text style to caption
                        textAlign: TextAlign.right,
                      ),
                      Text(
                        'Following ${profile.stats.followingCount == null ? 0 : profile.stats.followingCount} people',
                        style: Theme.of(context).textTheme.caption, // set text style to caption
                        textAlign: TextAlign.right,
                      ),
                    ],
                  ),
                ),
              ],
            )),
      ),
    );

Oddly, this doesn't affect my text anyway.奇怪的是,这不会影响我的文字。 It still stays black.它仍然保持黑色。

文字是黑色的

Probably there is something I don't understand about the themes.可能有一些我不明白的主题。 Is there a way to partially apply a theme (in this case, text color) to a widget that affects all direct and indirect children?有没有办法将主题(在本例中为文本颜色)部分应用到影响所有直接和间接子级的小部件?


Environment环境

  • Flutter 2.0.6 Flutter 2.0.6
  • Dart 2.12.3 Dart 2.12.3

Here is an example of how to use the global theme and local theme using Theme() to particular widgets.这是一个示例,说明如何使用Theme()对特定小部件使用全局主题和本地主题。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // Global Theme
        primarySwatch: Colors.blue,
        textTheme: Theme.of(context).textTheme.copyWith(
              bodyText2: TextStyle(
                color: Colors.orangeAccent,
                fontWeight: FontWeight.bold,
              ),
            ),
        cardTheme: CardTheme(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(20)),
            ),
            color: Colors.blueGrey),
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("List Builder"),
        ),
        body: HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Center(child: Text("Using MaterialApp theme")),
        Expanded(
          child: ListView.builder(
            itemCount: 4,
            itemBuilder: (context, index) {
              return Theme(
                // Child Theme
                data: Theme.of(context).copyWith(
                  textTheme: TextTheme(
                    bodyText2: TextStyle(color: Colors.greenAccent),
                  ),
                  cardTheme: CardTheme(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.all(Radius.circular(20)),
                    ),
                    color: Colors.red,
                  ),
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Card(
                      // Card Theme of Theme() data
                      child: Container(
                        width: MediaQuery.of(context).size.width * 0.4,
                        height: MediaQuery.of(context).size.height * 0.1,
                        child: Center(
                          child: Text(
                            "Hello (Using Theme())",
                          ),
                        ),
                      ),
                    ),
                    Container(
                      width: MediaQuery.of(context).size.width * 0.4,
                      height: MediaQuery.of(context).size.height * 0.1,
                      child: Card(
                        // Card Theme of MaterialApp
                        child: Center(
                          child: FittedBox(
                            child: Text(
                              "Welcome(card theme from MaterialApp)",
                              style: Theme.of(context).textTheme.bodyText2,
                            ),
                          ),
                        ),
                        shape: Theme.of(context).cardTheme.shape,
                        color: Theme.of(context).cardTheme.color,
                      ),
                    ),
                  ],
                ),
              );
            },
          ),
        ),
      ],
    );
  }
}

Here is the Output这是 Output 输出

TL;DR: Use Builder as a child of Theme if you'd like to apply the theme to all children. TL;DR:如果您想将主题应用于所有子项,请将Builder用作Theme的子项。


So, my code above seems to be using the context of build method, which is of parent.所以,我上面的代码似乎使用了build方法的上下文,它是父级的。 It changes the theme of the direct child of Theme .它改变了 Theme 的直接孩子的Theme This is quite counter-intuitive but luckily there is a way to initialize a brand new BuildContext using Builder widget.这是非常违反直觉的,但幸运的是,有一种方法可以使用Builder小部件初始化全新的BuildContext

So, if you want to apply the theme to all children whether they are direct or undirect children , always use Builder as a direct child of Theme .所以,如果你想将主题应用到所有孩子,无论他们是直接孩子还是非直接孩子,总是使用Builder作为Theme的直接孩子。

Theme(
  data: // your theme data here
  child: Builder(
    builder: (context) => // this is where you do stuff
  )
)

Notice how Builder provides a BuildContext named context ?注意Builder如何提供一个名为contextBuildContext This is a brand new context to work with and actually contains subtheme that we have just created rather than the context that is provided by build method.这是一个全新的上下文,实际上包含我们刚刚创建的子主题,而不是build方法提供的context So, when you create a Text widget under Builder widgeet somewhere:因此,当您在某处的Builder小部件下创建Text小部件时:

// under Builder widget somewhere
Text(
  'my text',
  style: Theme.of(context).textTheme.caption // we have a context here
)

The context here uses the context provided by Builder widget, not the build method, which makes it intuitive.这里的context使用的是Builder小部件提供的上下文,而不是build方法,这使它直观。

Also, the reason I use Theme.of is because I'd like to extend main theme, not create an empty theme .另外,我使用Theme.of的原因是因为我想扩展主主题,而不是创建一个空的主题 And Flutter has many predefined styles for texts such as bodyText1 , bodyText2 , heading1 (up to 6), caption etc. and I can use it with this method.并且 Flutter 有许多预定义的 styles 文本,例如bodyText1bodyText2heading1 (最多6个), caption等,我可以用这种方法使用它。

This is, at least, how I have solved the issue and the code makes sense.至少,这是我解决问题的方式,并且代码是有意义的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM