【问题标题】:How to change the Text color for a subtree in Flutter?如何更改 Flutter 中子树的文本颜色?
【发布时间】:2019-12-18 16:54:30
【问题描述】:

我希望特定Widget 中的每个Text 都具有白色,尽管它们都可以具有不同的大小。我知道我可以将每一个 Text 更改为白色,但我想让它变得更聪明,并为特定的 Widget 更改主题。

我试过了:

DefaultTextStyle.merge(
  style: TextStyle(color: Colors.white),
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      Text('Text 1',
        style: Theme.of(context).textTheme.title,
      ),
      Text('Text 2')
    ],
  ),
),

问题是Text 1 变成了黑色,而Text 2 变成了我想要的白色。

我认为使用DefaultTextStyle.merge 我仍然可以使用Theme.of(context) 来获得一般的TextTheme,仍然保持对DefaultTextStyle 的更改,但显然我错了。

在能够访问原始Theme 的其余部分的同时更改子树的文本颜色的正确方法是什么?

【问题讨论】:

    标签: flutter flutter-theme


    【解决方案1】:

    这里的问题是您正在使用此 style: Theme.of(context).textTheme.title 覆盖 style,它从您的应用程序的当前 Theme 获取来自 textThemetitle 样式。

    一种可能的解决方案是使用自定义样式但复制颜色属性,如下所示:

    DefaultTextStyle(
              style: TextStyle(color: Colors.white),
              child: Builder(
                builder: (context) {
                  return Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text(
                        'Text 1',
                        style: Theme.of(context).textTheme.title.copyWith(
                            color: DefaultTextStyle.of(context).style.color),
                      ),
                      Text('Text 2')
                    ],
                  );
                },
              ),
            ),
    

    简单的方法就是不要使用Theme中的textTheme,只需编写自己的样式而不指定颜色,如下所示:

    DefaultTextStyle(
              style: TextStyle(color: Colors.white),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    'Text 1',
                    //change the style without changing the color
                    style: TextStyle(fontSize: 40),
                  ),
                  Text('Text 2')
                ],
              ),
            ),
    

    更新

    我找到了另一种你可以使用的方法:

    Theme(
              data: Theme.of(context).copyWith(
                textTheme: Theme.of(context).textTheme.apply(
                      bodyColor: Colors.white,
                      displayColor: Colors.white,
                    ),
              ),
              child: DefaultTextStyle(
                style: TextStyle(color: Colors.white),
                child: Builder(
                  builder: (context) {
                    return Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Text(
                          'Text 1',
                          style: Theme.of(context).textTheme.title,
                        ),
                        Text('Text 2')
                      ],
                    );
                  },
                ),
              ),
            ),
    

    如果您不想使用Builder 小部件,请在父小部件(您的无状态小部件/有状态小部件)上使用Theme.of(context).copyWith

    【讨论】:

    • 所以没有办法以透明的方式覆盖子树的部分主题?使用Builder然后同时处理ThemeDefaultTextStyle看起来很麻烦
    • 你为什么不使用DefaultTextStyle.merge()
    • 其实也可以使用 DefaultTextStyle.merge。
    • 另一种方法是将您的小部件包装在 Theme 中,然后覆盖 TextTheme 并为 textTheme 中的所有样式设置相同的颜色
    • 我明白了...我将打开一个功能请求,以获得更简单的方法来实现这一点。
    猜你喜欢
    • 2023-03-11
    • 2021-09-18
    • 2020-10-22
    • 1970-01-01
    • 2021-08-22
    • 2021-08-23
    • 2018-09-17
    • 1970-01-01
    • 2018-08-18
    相关资源
    最近更新 更多