Gravid Banner

Styling Flutter (Part 2)

As part of my flutter journey I have been updating an app I wrote a few years ago, and applying some dynamic themes to it. In part one (Styling Flutter – Nightmare in Themesville) we looked at how to use the ThemeData object to apply a dynamic dark theme to light theme switch. In this post I will explore a few changes that have come along with Material 3 and a couple of gotchas that I have encountered in the process.

The first and most obvious change with Material3 is a switch in the ThemeData to declare that we are using it.

theme: ThemeData(
  useMaterial3: true,
);
Dart

The above code is actually unnecessary as the documentation says “This flag is true by default” – but it can be used to toggle Material3 off in order to test if any issues being seen are as a result of the change.

Another new addition is the ColorScheme fromSeed method which allows us to create a colorScheme from any colour and adds a lot more flexibility than the the primarySwatch attribute previously available

colorScheme: ColorScheme.fromSeed(seedColor: 0xff002244),
Dart

Other changes can be found in the Migrate to Material 3 guide.

So now to the gotchas.

ListTile title and subtitle color not being applied

The first of these took me a long while to track down. In several of my screens in the old app I was using ListTiles to display data

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: FutureBuilder<List<Map<String,String>>>(
      future: _fileList,
      builder : (context, snapshot) {
        if (snapshot.hasData) {
          return ListView.builder(
            itemCount: _fileList.length,
            itemBuilder: (BuildContext context, int index) {
              return ListTile(
                visualDensity: VisualDensity(horizontal: -4, vertical: -4),
                dense: true,
                title: Text(snapshot.data![index]["fileName"])),
                subtitle: Text(snapshot.data![index]["createDate"]),
                onTap: () { _openFile(context, snapshot.data![index]); },
                  trailing: IconButton(icon: Icon(Icons.delete, color: _theme.iconColor),  
                  onPressed: () {_deleteFile(context, snapshot.data![index]); },
                  visualDensity: VisualDensity (vertical: -4, horizontal: -4),
                ),
              );
            }
          );
        }
      )
    );
  }
Dart

It should have been a simple matter to create a theme for these tiles as follows:

theme: ThemeData(
  listTileTheme:  ListTileThemeData(
    titleTextStyle: TextStyle(
      fontSize: 24,
      color: Colors.orange,
    ),
    subtitleTextStyle: TextStyle(
      fontSize: 18,
      color: Colors.white,
    ),          
  ),
);
Dart

Except that the fontSize did not get applied. Any other TextStyle option applied to the list tile title and subtitle, but the text colour remained white. I tried a number of other options to fix the text colour – including setting all of the properties listed in the TextTheme documentation, but nothing made any difference until I noticed a hovering warning over the dense tag in my initial widget build saying

It is not recommended to set dense to true when ThemeData.useMaterial3 is true

Solution

Sure enough, removing dense immediately applied my colours to the title and subtitle.

Unfortunately it also made my ListTiles much bigger than I wanted them to be – so in the end I opted to replace them with an InkWell and a Column.

Flutter Engineering (Ad)


Comments

Leave a Reply

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