Introduce a,

The Theme class applies themes to child controls. Theme (Theme) describes the color and typography choices for the application. There are two types of Theme: global Theme and local Theme. The global Theme is the Theme created by the MaterialApp at the root of the application; A local Theme, on the other hand, is used to override a global Theme in a regional scope of the application.

Google website: API. Flutter. Dev/flutter/mat…

The constructor

Theme({Key key,
@required ThemeData data,
bool isMaterialAppTheme: false, 
@required Widget child })
Copy the code
  • ThemeData data: Save the Material theme’s typography styles, such as colors and fonts.
  • IsMaterialAppTheme: The default value is false, indicating whether the theme is designed for the material.
  • Child: child control.

Inheritance relationships

Diagnosticable -> DiagnosticableTree -> DiagnosticableTree -> StatelessWidget -> Theme.

Second, the ThemeData

From the Theme constructor, we can see that ThemeData is used to store the Theme and style information of the shared application in the Flutter, so let’s look at the official documentation to see what the ThemeData contains.

Diagnosticable -> Diagnosticable -> ThemeData

Constructor:

ThemeData({Brightness brightness,
MaterialColor primarySwatch, 
Color primaryColor, 
Brightness primaryColorBrightness, 
Color primaryColorLight, 
Color primaryColorDark, 
Color accentColor, 
Brightness accentColorBrightness,
Color canvasColor, 
Color scaffoldBackgroundColor, 
Color bottomAppBarColor, 
Color cardColor, 
Color dividerColor, 
Color focusColor, 
Color hoverColor, 
Color highlightColor, 
Color splashColor, 
InteractiveInkFeatureFactory splashFactory, 
Color selectedRowColor, 
Color unselectedWidgetColor, 
Color disabledColor, 
Color buttonColor, 
ButtonThemeData buttonTheme,
Color secondaryHeaderColor,
Color textSelectionColor,
Color cursorColor, 
Color textSelectionHandleColor, 
Color backgroundColor, 
Color dialogBackgroundColor, 
Color indicatorColor, 
Color hintColor, 
Color errorColor, 
Color toggleableActiveColor, 
String fontFamily, 
TextTheme textTheme, 
TextTheme primaryTextTheme, 
TextTheme accentTextTheme, 
InputDecorationTheme inputDecorationTheme, 
IconThemeData iconTheme, 
IconThemeData primaryIconTheme, 
IconThemeData accentIconTheme, 
SliderThemeData sliderTheme, 
TabBarTheme tabBarTheme,
CardTheme cardTheme, 
ChipThemeData chipTheme, 
TargetPlatform platform, 
MaterialTapTargetSize materialTapTargetSize, 
PageTransitionsTheme pageTransitionsTheme,
AppBarTheme appBarTheme,
BottomAppBarTheme bottomAppBarTheme, 
ColorScheme colorScheme, 
DialogTheme dialogTheme, 
FloatingActionButtonThemeData floatingActionButtonTheme, 
Typography typography, 
CupertinoThemeData cupertinoOverrideTheme, 
SnackBarThemeData snackBarTheme, 
BottomSheetThemeData bottomSheetTheme })
Copy the code

As you can see from its constructor, it mainly saves the various colors and Settings for fonts, Icon styles, and so on. Since there are too many properties, let’s pick some common ones to talk about:

  • Thumbs-thumbtype, the overall theme brightness of the application. Used for widgets such as buttons to determine what color to select when primaryColor or accentColor is not used. When the brightness is low, the canvas, cards and primary colors are all dark. When the brightness is light, the color of the canvas and card is bright, and the darkness of the primary color varies according to the primary color brightness. When the brightness is low, the contrast between the primaryColor and the card and canvas color is poor; When the brightness is low, use white or bright blue to contrast.

  • PrimarySwatch – MaterialColor type, Material theme defines a color sample that has ten shades of color. The larger the value, the darker the color. The 10 valid indexes are: 50,100,200… , 900. The default is the median value of 500.

  • PrimaryColor – Color type, the background Color of the main part of the App (ToolBar,Tabbar, etc.)

  • PrimaryColorBrightness – Brightness of the primaryColor, used to determine the text and icon color set above the primaryColor (for example, Toolbar Text).

  • PrimaryColorLight – Color type, a lighter version of primaryColor

  • Primarycolordark-color type, darker version of primaryColor

  • AccentColor – Color type, foreground Color (button, text, overlay edge effect, etc.)

  • Accentcolorsparent-brightness type, accentColorBrightness. Used to determine the color of the text and ICONS above the accentColor (for example, ICONS on a FloatingButton)

  • CanvasColor – The Color type, the default Color of MaterialType. Canvas Material.

  • Scaffoldbackgroundcolor-color type, which is the Material default Color under Scaffold and is used as the background Color on the pages inside your Materia application or app.

  • BottomAppBarColor – Color type, the default Color of bottomAppBarColor. This can be overridden by specifying bottomAppbar.color.

  • CardColor – Color type, the Material Color used on the Card.

  • The Dividercolor-color type, the Color of Dividers and popupmendividers, is also used between the rows of ListTiles and DataTables. To create an appropriate boundary using this color, consider divider.CreateBorderside.

  • HighlightColor – the Color type used for ink splash animations or to indicate the highlightColor when the menu is selected

  • SplashColor – Color type, the Color of the ink splash

  • SplashFactory – InteractiveInkFeatureFactory type, define InkWall and InkResponse made into ink splashes of appearance.

  • SelectedRowColor – Color type, used to highlight the Color of the selected row.

  • UnselectedWidgetColor – Color type, the Color used when the widget is inactive (but enabled). For example, unchecked check boxes. Often contrasted with accentColor.

  • DisabledColor – Color type, invalid Color of widgets, regardless of their status. For example, a disabled check box (which can be selected or unselected).

  • ButtonColor – the default fill Color used for RaisedButtons in the Color type, Material.

  • ButtonTheme – The ButtonThemeData type, which defines the default configuration for button widgets, such as RaisedButton and FlatButton.

  • SecondaryHeaderColor – The Color of the PaginatedDataTable header when the row is selected

  • TextSelectionColor – Color type, the Color that TextField (such as TextField) is selected for.

  • CursorColor – Color type, the Color of the cursor in a Material-style TextField such as TextField.

  • TextSelectionHandleColor – Color type that adjusts the Color of the handle to the currently selected part of the text.

  • BackgroundColor – Color type, the Color compared with primaryColor (for example, for the rest of the progress bar).

  • Dialog BackgroundColor – Color type, Color type, the background Color of the Dialog element

  • IndicatorColor – Color type, the indicatorColor selected in the TabBar option.

  • HintColor – Color type used to indicate the Color of text or placeholder text, such as in TextField.

  • ErrorColor – the Color type used to enter a validation errorColor, such as in a TextField.

  • ToggleableActiveColor – Color type, used to highlight the Color of the active state of Switch widgets such as Switch, Radio, and Checkbox.

  • FontFamily – String type, font type

  • TextTheme – textTheme type, the color of the text compared with the card and canvas

  • PrimaryTextTheme – TextTheme type, the TextTheme that contrasts with the primary color.

  • AccentTextTheme – TextTheme type, which contrasts the TextTheme with accent color.

  • InputDecorationTheme – The inputDecorationTheme type, based on which the default InputDecoration values of InputDecorator, TextField, and TextFormField are based.

  • IconTheme – IconThemeData type, the iconTheme that contrasts the color of the card and canvas.

  • PrimaryIconTheme – IconThemeData type, the icon theme that contrasts with the primary color.

  • AccentIconTheme – IconThemeData type that contrasts the icon theme with the foreground color.

  • SliderTheme – The SliderThemeData type, used to render the color and shape of the Slider.

  • TabBarTheme – The tabBarTheme type, a theme, is used to customize the size, shape, and color of the TAB bar indicator.

  • ChipTheme – ChipThemeData type, used for the Chip color and style

  • Platform-targetplatform type. The widget should fit the TargetPlatform.

  • MaterialTapTargetSize – The type of materialTapTargetSize specifies the hit test size of a specific material component.

  • PageTransitionsTheme – The default MaterialPageRoute conversion of the pageTransitionsTheme type for each target platform.

  • ColorScheme The colorScheme type, a set of 13 colors, can be used to configure the color properties of most components.

  • Typography – the type of typography, which is used to configure the color and geometric TextTheme values of TextTheme, primaryTextTheme, and accentTextTheme.

Theme. Of method

It’s a static method. The child control gets the ThemeData object for the current Theme by using Theme. Of, and when the control uses Theme. Of, if the Theme changes later, it is automatically rebuilt so that the changes can be applied. We can see the current application’s color scheme by using Theme. Of.

Themedata.of method code:

ThemeData of (
BuildContext context, {
bool shadowThemeOnly: false
})
Copy the code

The ThemeData data is from the most recent instance of the Theme for a given context. If the given context is contained in a Localizations component that provides MaterialLocalizations, then the returned data will be localized according to the most recent available MaterialLocalizations. If there is no theme in the given build context, the default is the new ThemeData.Fallback.

The following is an example:

@override
Widget build(BuildContext context) {
  return Text(
    'Theme Example',
    style: Theme.of(context).textTheme.title,
  );
}
Copy the code

So far we have seen how to set up the theme of the Flutter, which is divided into global themes and local themes. Let’s look at the scenarios and differences between these two approaches.

4. Global themes

When creating an application global theme, we simply provide an ThemeData object to the MaterialApp. If the constructor does not set ThemeData, the Flutter creates a default theme. Let’s put this into practice by writing a simple example of a custom global theme:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo', theme: theme data (brightness: brightness. Light, // Specify the brightness theme. The options are white or black. PrimaryColor: color. blue[800], // here we choose blue as the base color. AccentColor: color.lightblue [100]), // here we choose lightBlue as the accentColor value. home: ThemeTest(), ); } } class ThemeTest extends StatelessWidget { @override Widget build(BuildContext context) {return Scaffold(
      appBar: AppBar(
        title: Text("ThemeTest"), body: Container(color: theme.of (context).primarycolor, // Content background color margin: edgeinsets.all (100.0), padding: EdgeInsets. All (10.0), the child: the Text ("MaterialApp Theme Color", // Style: TextStyle(fontSize: 20, color: Theme. Of (context).Accentcolor), // Style: TextStyle(fontSize: 20, color: Theme. textAlign: TextAlign.center, ), ), ); }}Copy the code

The renderings are as follows:

5. Local themes

Local topics are used to override global topics in certain areas of the application. Once we define a Theme, we can use it in the Build method of the Widget via the theme.of (context) method. Theme. Of (context) looks up the Widget tree and returns the nearest Theme in the tree. If there is a separate local Theme definition on top of the Widget, the value of that Theme is returned. If not, the App global theme is returned. Let’s look at the main ways to create:

5.1 Create the Theme object again

Create an instance by recreating Theme, and recreate ThemeData and assign it to data. Then specify the Child Widget and pass the ThemeData to the Theme Widget as follows:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo', theme: theme data (brightness: brightness. Light, // Specify the brightness theme. The options are white or black. PrimaryColor: color. blue[800], // here we choose blue as the base color. AccentColor: color.lightblue [100]), // here we choose lightBlue as the accentColor value. home: Theme( data: ThemeData(accentColor: Colors.yellow), child: ThemeTest())); }} class ThemeTest extends StatelessWidget {@Override Widget build(BuildContext Context) {return Scaffold(
      appBar: AppBar(
        title: Text("ThemeTest"),), body: Container(color: theme.of (context). PrimaryColor, Margin: EdgeInsets. All (100.0), padding: EdgeInsets. All (10.0), the child: the Text ("MaterialApp Theme Color", style: TextStyle(fontSize: 20, color: Theme. Of (context).accentcolor), // textAlign: textalign.center,),); }}Copy the code

The renderings are as follows:

The local topic is invalid

For this to work, we need to set a local Theme in the parent layer of the Widget. If we use it directly in the Widget specified in the child property of the local Theme, we get the system’s global Theme.

Here is an example:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo', theme: theme data (brightness: brightness. Light, // Specify the brightness theme. The options are white or black. PrimaryColor: color. blue[800], // here we choose blue as the base color. AccentColor: color.white), // set it to white. home: ThemeTest(), ); } } class ThemeTest extends StatelessWidget { @override Widget build(BuildContext context) {return Scaffold(
      appBar: AppBar(
        title: Text("ThemeTest"), body: Container(color: theme.of (context). PrimaryColor, Margin: EdgeInsets. All (100.0), padding: EdgeInsets. All (10.0), child: Theme(data: ThemeData(accentColor: // Create a local Theme with accentColor green. If the Child of the local Theme is Text, the reference to the local Theme color will not take effect. Instead, the value of the global Theme will be the value of the top layer of the local Theme. child: Text("MaterialApp Theme Color", style: TextStyle(fontSize: 20, color: Theme. Of (context).accentcolor), // Application Theme color textAlign: textalign.center,)),); }}Copy the code

The renderings are as follows:

As you can see from the screenshot, the color of the Text is still white, not red as we expected, so we need to pay extra attention to this when using it.

5.2 Extending the parent theme

In addition to creating a Theme object to use local themes, we can do this by using the copyWith method. This way, when we modify the parent Theme, we don’t need to overwrite all the Theme properties, but just specify the properties we want to change.

Instead of:

data: ThemeData(accentColor: Colors.yellow)
Copy the code

To:

Theme.of(context).copyWith(accentColor: Colors.yellow)
Copy the code

In this way, our local Theme can still use the value of the preceding Theme property, except that accentColor is changed to the specified value, instead of becoming the system default.

5.3 Set themes based on the device platform

In addition to the above two approaches, we can also provide different themes based on the platform type of device (iOS, Android and Fuchsia) :

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
 
final ThemeData iOSTheme = ThemeData(
    brightness: Brightness.light,
    primaryColor: Colors.grey[600],
    accentColor: Colors.white,
  );

final ThemeData androidTheme = ThemeData(
    brightness: Brightness.dark,
    primaryColor: Colors.yellow[300],
    accentColor: Colors.deepPurple[800],
  );
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        brightness: Brightness.light,
        primaryColor: Colors.grey[100],
        accentColor: Colors.white,
      ),
      home: Theme(
          data: defaultTargetPlatform == TargetPlatform.android
              ? androidTheme
              : iOSTheme,
          child: ThemeTest()),
    );
  }
}

class ThemeTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ThemeTest"),), body: Container(color: theme.of (context). PrimaryColor, Margin: EdgeInsets. All (100.0), padding: EdgeInsets. All (10.0), the child: the Text ("MaterialApp Theme Color", style: TextStyle(fontSize: 20, color: Theme.of(context).accentColor), textAlign: TextAlign.center, )), ); }}Copy the code

Android renderings:

IOS renderings:

Six, summarized

This article focuses on the common methods and properties of a Theme. At the same time, the setting methods of global theme, local theme and different platform theme are also given in detail. The theme Settings in Flutter are relatively flexible and can be practiced a lot.

The author



xiaosongzeem