Philip
Philip

Reputation: 678

Flutter - How to style different color text for Flat Buttons depending on whether button is in appbar or main screen

In my styles.dart I have the following theme:

final ThemeData purpleTheme = ThemeData(
    brightness: Brightness.light,
    primaryColor: PURPLE,
    buttonColor: GREEN,
    fontFamily: FontNameDefault,
    buttonTheme: ButtonThemeData(
        textTheme: ButtonTextTheme
            .primary, // TODO: This is making the flat buttons all appear in blue instead of purple
        buttonColor: GREEN,
        height: 45),
    appBarTheme: AppBarTheme(
      textTheme: TextTheme(title: AppBarTextStyle, button: AppBarTextStyle),
      iconTheme: new IconThemeData(color: Colors.white),
      brightness: Brightness.dark,
      color: PURPLE,
    ),
    textTheme: TextTheme(
        title: TitleTextStyle,
        body1: Body1TextStyle,
        subtitle: SubtitleTextStyle));

With the above theme setting, The buttonTheme textTheme is ButtonTextTheme.primary. The primary color seems to be blue for some reason, even though nowhewere in my styling do I use blue. When I add

colorScheme: ColorScheme.light().copyWith(primary: PURPLE)

To the style, the primary color becomes purple. However, I would like the flat buttons in the purple appbar to use white text, and flat buttons in the white screen to use purple text. How can I get that coded into the ThemeData?

Upvotes: 1

Views: 1847

Answers (1)

Darish
Darish

Reputation: 11481

The use case you have is already well defined in the Material theme spec.

Here I am going to explain how to style color of any widget (eg: button/ text/ customWidget..) depending on the parent widget color.

example use cases:

  1. primary colored text on white colored appBar
  2. white colored text on primary colored appBar
  3. black color text on white color surface
  4. primary color text on white color surface

Here you go.

Step 1:

First of all, Define a primary color swatch that define all the variants from 50 to 900.

final MaterialColor lightPrimaryColorSwatch = MaterialColor(
    0xff4f9af0,
    {
      50: Color(0xffeaf3fd),
      100: Color(0xffcae1fb),
      200: Color(0xffa7cdf8),
      300: Color(0xff84b8f5),
      400: Color(0xff69a9f2),
      500: Color(0xff4f9af0),
      600: Color(0xff4892ee),
      700: Color(0xff3f88ec),
      800: Color(0xff367ee9),
      900: Color(0xff266ce5),
    },
  );

Step 2:

You need to define a ColorScheme object that define all the 12 colors of material spec.

final ColorScheme lightColorScheme = ColorScheme(
        brightness: Brightness.light,
        primary: Color(0xff4f9af0),
        primaryVariant: Color(0xff2c86ed),
        secondary: Color(0xff0863c4),
        secondaryVariant: Color(0xff259b24),
        error: Color(0xffb00020),
        background: Color(0xfff7f8fa),
        onError: Colors.white,
        onSecondary: Colors.white,
        onBackground: Color(0xff292929),
        onPrimary: Colors.white,
        onSurface: Color(0xff292929),
        surface: Colors.white,
      );

Step 3:

Define theme data for your MaterialApp using the above defined values.

 return MaterialApp(

      theme: ThemeData(
        brightness: Brightness.light,
        primarySwatch: lightPrimaryColorSwatch,
        primaryColor: lightColorScheme.primary,
        primaryColorDark: lightColorScheme.primaryVariant,
        errorColor: lightColorScheme.error,
        colorScheme: lightColorScheme,
        primaryColorBrightness: Brightness.dark,
        accentColorBrightness: Brightness.dark,
        accentColor: lightColorScheme.secondary,
        primaryColorLight: lightColorScheme.secondaryVariant,
        backgroundColor: lightColorScheme.background,
        canvasColor: lightColorScheme.background,
      ),
    //... other attributes go here
  );

Now you are all set. From now on, you can use those 12 colors for any type of combo that you wish.

Here is an example.

import 'package:flutter/material.dart';


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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MaterialColor lightPrimaryColorSwatch = MaterialColor(
      0xff4f9af0,
      {
        50: Color(0xffeaf3fd),
        100: Color(0xffcae1fb),
        200: Color(0xffa7cdf8),
        300: Color(0xff84b8f5),
        400: Color(0xff69a9f2),
        500: Color(0xff4f9af0),
        600: Color(0xff4892ee),
        700: Color(0xff3f88ec),
        800: Color(0xff367ee9),
        900: Color(0xff266ce5),
      },
    );

    final ColorScheme lightColorScheme = ColorScheme(
      brightness: Brightness.light,
      primary: Color(0xff4f9af0),
      primaryVariant: Color(0xff2c86ed),
      secondary: Color(0xff0863c4),
      secondaryVariant: Color(0xff259b24),
      error: Color(0xffb00020),
      background: Color(0xfff7f8fa),
      onError: Colors.white,
      onSecondary: Colors.white,
      onBackground: Color(0xff292929),
      onPrimary: Colors.white,
      onSurface: Color(0xff292929),
      surface: Colors.white,
    );
    return MaterialApp(
      theme: ThemeData(
        brightness: Brightness.light,
        primarySwatch: lightPrimaryColorSwatch,
        primaryColor: lightColorScheme.primary,
        primaryColorDark: lightColorScheme.primaryVariant,
        errorColor: lightColorScheme.error,
        colorScheme: lightColorScheme,
        primaryColorBrightness: Brightness.dark,
        accentColorBrightness: Brightness.dark,
        accentColor: lightColorScheme.secondary,
        primaryColorLight: lightColorScheme.secondaryVariant,
        backgroundColor: lightColorScheme.background,
        canvasColor: lightColorScheme.background,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            SizedBox(height: 8.0),
           ///white color text on container with primary color
            Container(
                color: Theme.of(context).colorScheme.primary,
                height: 40.0,
                width: 100.0,
                alignment: Alignment.center,
                child: Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text('Hello, World!',
                      style: Theme.of(context).textTheme.bodyText2.copyWith(
                          color: Theme.of(context).colorScheme.onPrimary)),
                )),
            SizedBox(height: 8.0),
            ///Primary color text on  white color container.
            Container(
                color: Theme.of(context).colorScheme.surface,
                height: 40.0,
                width: 100.0,
                alignment: Alignment.center,
                child: Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text('Hello, World!',
                      style: Theme.of(context)
                          .textTheme
                          .bodyText2
                          .copyWith(color: Theme.of(context).colorScheme.primary)),
                )),
          ],
        );
      }
    }

You can find a live demo here.

Upvotes: 3

Related Questions