skip to Main Content

I can’t make ExpansionTile ‘textColor’ and ‘collapsedTextColor’ properties work with Text widgets that have been styled with some TextStyle I created with "copyWith" in Flutter.

Here is an example:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ExpansionTile/Text color bug',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'ExpansionTile/Text color bug main page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    TextStyle aTextStyle = Theme.of(context)
        .textTheme
        .bodyMedium!
        .copyWith(fontStyle: FontStyle.italic);
    
    // If you comment out the following line, the text gets from white to black.
    // It never gets orange/blue as expected.
    aTextStyle = _copyUnsettingColor(aTextStyle);

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: ListView(
        children: [
          const ExpansionTile(
            title: Text('Unstyled text'),
            textColor: Colors.amber,
            collapsedTextColor: Colors.blue,
          ),
          ExpansionTile(
            title: Text(
              'Styled text',
              style: aTextStyle,
            ),
            textColor: Colors.amber,
            collapsedTextColor: Colors.blue,
          ),
        ],
      ),
    );
  }

  TextStyle _copyUnsettingColor(TextStyle style) {
    final TextStyle uncoloredStyle = TextStyle(
      debugLabel: style.debugLabel,
      decoration: style.decoration,
      decorationStyle: style.decorationStyle,
      decorationThickness: style.decorationThickness,
      fontFamily: style.fontFamily,
      fontFamilyFallback: style.fontFamilyFallback,
      fontFeatures: style.fontFeatures,
      fontSize: style.fontSize,
      fontStyle: style.fontStyle,
      fontVariations: style.fontVariations,
      fontWeight: style.fontWeight,
      height: style.height,
      inherit: style.inherit,
      leadingDistribution: style.leadingDistribution,
      letterSpacing: style.letterSpacing,
      locale: style.locale,
      overflow: style.overflow,
      shadows: style.shadows,
      textBaseline: style.textBaseline,
      wordSpacing: style.wordSpacing,
    );
    return uncoloredStyle;
  }
}

As you can see, the first ExpansionTile Text is colored as defined by ExpansionTile textColor and collapsedTextColor properties.

The second one no.

The _copyUnsettingColor method was a last resource experience to try to make ExpansionTile textColor and collapsedTextColor properties work but it just changed the color of the text from black to white, not the orange/blue I was expecting.

2

Answers


  1. Chosen as BEST ANSWER

    Apparently the solution if simply to comment out the inherit property in _copyUnsettingColor.

    This is and the color property should not be present on the TextStyle used for Text widgets in ExpansionTile if you want to use ExpansionTile's text color properties.


  2. Specify a TextStyle directly in the styled TextField widget’s style property. This way it will merge the style you set here with the other settings coming from the ExpansionTile:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'ExpansionTile/Text color bug',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const MyHomePage(title: 'ExpansionTile/Text color bug main page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key, required this.title});
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {    
        return Scaffold(
          appBar: AppBar(
            backgroundColor: Theme.of(context).colorScheme.inversePrimary,
            title: Text(widget.title),
          ),
          body: ListView(
            children: [
              const ExpansionTile(
                title: Text('Unstyled text'),
                textColor: Colors.amber,
                collapsedTextColor: Colors.blue,
              ),
              ExpansionTile(
                title: Text(
                  'Styled text',
                  style: TextStyle(fontStyle: FontStyle.italic),
                ),
                textColor: Colors.amber,
                collapsedTextColor: Colors.blue,
              ),
            ],
          ),
        );
      }
    }
    

    (I think the problem with your original code is that the copyWith takes all style defined in the theme, including textColor. And that prevents the ExpansionTile to use collapsedTextColor etc. because the custom style overrides the default styling.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search