marse
marse

Reputation: 313

Declaring one or more custom Themes

I'm trying to create a custom theme inside a flutter project.

I've created a separate file (mycolors.dart) where i defined some colors (const myPrimaryColor = const Color(0xFFFF3900); etc etc)

Then, in main.dart i'm referring to these colors and a custom font but inside the Widget build...

How can I isolate the theme data (colors and font/text styles), let's say "separately", and to refer to it inside the class?

Can I also define 2 different themes and use them later in the project?

Many thanks.

import 'package:flutter/material.dart';
import 'package:my_repository/mycolors.dart';
import 'package:flutter_statusbarcolor/flutter_statusbarcolor.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    FlutterStatusbarcolor.setStatusBarColor(myPrimaryColor);
    return MaterialApp(
      theme: ThemeData(
        fontFamily: 'Raleway',
        primaryColor: myPrimaryColor,
        accentColor: myAccentColor,
        scaffoldBackgroundColor: myBackgroundColor,
        cardColor: mySurfaceColor,
        textSelectionColor: myPrimaryColor,
        errorColor: myErrorColor,
      ),
      home: Scaffold( ....

Upvotes: 3

Views: 5552

Answers (3)

Fahad Rana
Fahad Rana

Reputation: 11

   final ThemeData customTheme = _buildcustomTheme();

    ThemeData _buildcustomTheme() {

    return customThemeFoundation;

     }

            ThemeData customThemeFoundation =ThemeData(

       brightness: Brightness.dark,
         primaryColor: Color.fromRGBO(40, 204, 86, 1),
       accentColor: Colors.cyan[600],


             fontFamily: 'Georgia',


     textTheme: TextTheme(
             headline1: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold),
         headline6: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic),
           bodyText2: TextStyle(fontSize: 14.0, fontFamily: 'Hind'),
               ),
        



   and in main.dart just call it by
           import 'theme.dart';
           and just relpace theme:{.....}  with   theme: customTheme,

Upvotes: -2

Ali Qanbari
Ali Qanbari

Reputation: 3111

You can define your themes in a class and then call ThemeName().theme.

here is how I have a theme file in my app:

class MuskTheme {

  ...

  ThemeData get theme => ThemeData(
    brightness: Brightness.dark,
    primarySwatch: musk,
    accentColor: accentColor,
    fontFamily: fontFamily,
    backgroundColor: musk,
    canvasColor:canvasColor,
    textTheme: _textTheme,
    iconTheme: _iconTheme,
    cardColor: Color(0xff313A49),
    appBarTheme: AppBarTheme(color: canvasColor,elevation: 0),
    dialogBackgroundColor: canvasColor,
    snackBarTheme: SnackBarThemeData(
      backgroundColor: musk[800],
      actionTextColor: accentColor,
    ),
  );

...

}

for changing your theme during runtime you need to rebuild the MaterialApp widget by implementing a stateful widget that is higher than MaterialApp and can rebuild it upon request.

example implementation:

class ThemeChanger extends StatefulWidget {
  final ThemeData initialTheme;
  final MaterialApp Function(BuildContext context, ThemeData theme)
      materialAppBuilder;

  const ThemeChanger({Key key, this.initialTheme, this.materialAppBuilder})
      : super(key: key);

  @override
  _ThemeChangerState createState() => _ThemeChangerState();

  static void setTheme(BuildContext context, ThemeData theme) {
    var state = context.ancestorStateOfType(TypeMatcher<_ThemeChangerState>())
        as _ThemeChangerState;
      state.setState(() {
        state.theme = theme;
      });
  }
}

class _ThemeChangerState extends State<ThemeChanger> {
  ThemeData theme;

  @override
  void initState() {
    super.initState();
    theme = widget.initialTheme;
  }

  @override
  Widget build(BuildContext context) {
    return widget.materialAppBuilder(context, theme);
  }
}

then you'll need to build your MaterialApp with it:

class ThemeChangingApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ThemeChanger(
      initialTheme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      materialAppBuilder: (context, theme) {
        return MaterialApp(
          theme: theme,
          home: StartingPage(),
        );
      },
    );
  }
}

and in your app you can change the theme like this:

class StartingPage extends StatefulWidget {
  @override
  _StartingPageState createState() => _StartingPageState();
}

class _StartingPageState extends State<StartingPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        child: Center(
          child: FlatButton(
            child: Text('change theme to orange'),
            onPressed: () {
              ThemeChanger.setTheme(
                  context,
                  ThemeData(
                    primarySwatch: Colors.orange,
                  ));
            },
          ),
        ),
      ),
    );
  }
}

this package does a similar thing.

Upvotes: 9

Ali Qanbari
Ali Qanbari

Reputation: 3111

You can build a scaffold with a different theme just by warpping it with a Theme widget:

class StartingPage extends StatefulWidget {
  @override
  _StartingPageState createState() => _StartingPageState();
}

class _StartingPageState extends State<StartingPage> {
  @override
  Widget build(BuildContext context) {
    return Theme(
      data: ThemeData.dark(),
      child: Scaffold(
        appBar: AppBar(),
        body: Container(
          child: Center(
            child: Text('test'),
          ),
        ),
      ),
    );
  }
}

Upvotes: 0

Related Questions