skip to Main Content

I’m trying to set a custom foreground and background colour on an AppBar in flutter, but I’m struggling to find a neat approach to dealing with themes in flutter.

In my example below, I create my own theme, then in the AppBar I set the background and foreground to use primary and onPrimary from the theme. I also want to have some small text, so I use textTheme.titleSmall, but that causes it to lose the colour it would otherwise inherit form the AppBar.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF1E2EB8)),
      ),
      home: Builder(
        builder: (context) {
          return Scaffold(
            appBar: AppBar(
              backgroundColor: Theme.of(context).colorScheme.primary,
              foregroundColor: Theme.of(context).colorScheme.onPrimary,
              title: Row(
                children: [
                  const Text('Hello'),
                  Text('World', style: Theme.of(context).textTheme.titleSmall ),
                ],
              ),
            ),
          );
        }
      ),
    );
  }
}

I know I could just set the font size manually, but that kind of defeats the purpose of having a theme where I can specify globally how big "small titles" should be.

I could also use textTheme.titleSmall.copyWith(colour: Theme.of(context).colorScheme.onPrimary) but that couples the text to the AppBar since its assuming it will be used somewhere where the background colour is set to primary. In a realistic scenario where these things are in separate widgets and can be used in different places where the background colour would be different, this would prevent reusability.

What’s the best way to achieve this kind of thing without coupling widgets to each other and without using magic values?

2

Answers


  1. Where to specify globally how big "small titles" should be?

    At the theme data.

    ThemeData(
      textTheme: TextTheme(
        titleSmall: TextStyle(
          // Styles here
        )
      )
    )
    
    Login or Signup to reply.
  2. When you use the TextStyle constructor, it does inherit every element from the parent context except the parameters you defined.

    You can set a global app bar theme in your ThemeData in the appBarTheme parameter:

    ThemeData(
      // ...
      appBarTheme: AppBarTheme(
        backgroundColor: // ...
      ),
    )
    

    And again, the AppBarTheme constructor will inherit all the default values except those parameters that you set.

    The same goes for TextTheme, which you can set in the textTheme parameter of ThemeData:

    ThemeData(
      // ...
      textTheme: TextTheme(
        titleSmall: // ...
      )
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search