How to change the Text color for a subtree in Flutter?

Issue

I want that every Text inside a particular Widget will have a white color, although they all can have different sizes. I know I can change every singe Text to have a white color, but I want to make it smart and change the Theme for that particular Widget.

I tried this:

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')
    ],
  ),
),

The problem is Text 1 becomes black and Text 2 is white as I wanted.

I thought that using DefaultTextStyle.merge I would still be able to use Theme.of(context) to get the general TextTheme, still maintaining the changes over DefaultTextStyle but apparently I am wrong.

What’s the correct way of changing a sub-tree’s text color, while being able to access the rest of the original Theme?

Solution

The issue here is that you are overwriting the style using this style: Theme.of(context).textTheme.title, it’s getting the title style from textTheme from you the current Theme of your app.

A possible solution is to use a custom style but copying the color property, like this :

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')
                ],
              );
            },
          ),
        ),

The easy way is just not using the textTheme from your Theme, just write your own style without specifying the color, like this:

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')
            ],
          ),
        ),

UPDATE

I found another way what you can use :

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')
                  ],
                );
              },
            ),
          ),
        ),

If you don’t want to use the Builder widget, use the Theme.of(context).copyWith on the parent widget (of your statelesswidget/statefulwidget).

Answered By – diegoveloper

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *