How to set a different theme for a screen?

Issue

I created the Friendly Chat app and want to add a new screen with a different theme but it doesn’t work 🙁

The whole app has a Brightness.dark theme:

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

class MyApp extends StatelessWidget {

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    print("build MaterialApp");
    return new MaterialApp(
      title: 'Friendly Chat',
      theme: kTheme,
      home: new ChatScreen(),
      routes: <String, WidgetBuilder>{
        SettingsScreen.PATH: (BuildContext context) => new SettingsScreen()
      },
    );
  }
}

final ThemeData kTheme = new ThemeData(
  primarySwatch: Colors.indigo,
  primaryColor: Colors.indigoAccent[100],
  primaryColorBrightness: Brightness.dark,
);

When the user clicks a button I push the settings screen:

Map results = await Navigator.of(context).pushNamed(SettingsScreen.PATH);

In the settings screen I change the AppBar‘s backgroundColor and brightness but the new/different brightness has no effect (changing the backgroundColor works)

class SettingsScreen extends StatefulWidget {

  @override
  State createState() => new SettingsScreenState();
}

class SettingsScreenState extends State<SettingsScreen> {

  @override
  Widget build(BuildContext context) {
    return new WillPopScope(
      onWillPop: _onWillPop,
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text("Settings"),
          backgroundColor: Colors.amberAccent[700],
          brightness: Brightness.light,
        ),
      ),
    );
  }
}

How can I change the settings screen AppBar theme to a light one?

EDIT

At the end I want:

  • all screens have a dark AppBar background color with white title and icons

  • settings screen (only) has a light AppBar background color with dark title and icons

Bonus points: How to set a different theme for the whole screen and not only for the AppBar

Solution

You can override the current theme by wrapping the desired widget in a Theme widget

Typically you’d have something similar to :

class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
  final AppBar appBar;

  CustomAppBar(): appBar = new AppBar();

  @override
  Widget build(BuildContext context) {
    return new Theme(
      child: appBar,
      data: new ThemeData.dark()
    );
  }

  @override
  Size get preferredSize => appBar.preferredSize;
}

Had to make a custom class because Scaffold requires a PreferredSizeWidget.

EDIT

To answer your “Bonus Point”, it’s dead simple.

Instead of wrapping the AppBar in a Theme, wrap the Scaffold instead.

Answered By – Rémi Rousselet

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published