The Provider of the Flutter global controller is used to control the global topic, etc

  • SwitchListTile
  • ExpansionTile
  • Provider Global Controller

It is easier to accept your own failure than to accept the failure of others. There are always reasons for their failure, for example, time is not my own, the opponent is too sinister and so on. The failure of others is deserved. It is easier to accept your own success than to accept the success of others. It is easier to accept weakness in yourself than in others. Their weak, because a lot of people need to take care of themselves, so can not casually try to be brave.

Let’s take a look at today’s results:

Rendering (1.1) :

Analysis:

  • Use SwitchListTile() for the layout of the night mode buttons
  • ExpansionTile() for color-themed button layouts
  • Use plugin provider: ^4.3.2+3 for global control

SwitchListTile

Night mode button bold is a mandatory parameter

SwitchListTile parameters type instructions
title Widget Main title
value bool If the selected
subtitle Widget subtitle
dense bool Vertical dense center The default value is false
activeColor Color Slide the ball when selected
activeTrackColor Color Select the color of the guide rail
inactiveThumbColor Color Slide ball color when unchecked
inactiveTrackColor Color Color of the guide rail if this parameter is not selected
secondary Widget Left child Widget(usually for images)
selected bool Whether to follow activeColor color change
onChanged ValueChanged Respond to events
// Night mode
  bool isNight = true;

// Night mode
  SwitchListTile initSwitchListTile(BuildContext context) {
    return SwitchListTile(
      title: Text("Night mode ${isNight? "Has been open":"Did not open"}"),
      // Button to turn on color
      activeColor: Colors.blue,
      // Respond to events
      onChanged: (bool value) {
        setState(() {
          isNight = value;
          Toast.toast(context, msg: "$value");
        });
      },
      value: isNight,
    );
  }
Copy the code

This code is very simple to change the current state by clicking a button

Rendering (1.2) :

ExpansionTile

Bold is a mandatory parameter

ExpansionTile parameters type instructions
leading Widget The upper left corner Widget
title Widget Text prompt
initiallyExpanded bool Whether to expand by default
trailing Widget Rightmost drop-down list
children List Display text at the bottom
backgroundColor Color The background color when expanded
onExpansionChanged bool Expand close Listening
subtitle Widget Auxiliary words
childrenPadding EdgeInsets Expand text indentation
tilePadding EdgeInsets Title Indented text
expandedAlignment Alignment alignment
 // Color theme
  Widget initExpansionTile(a) {
    return ExpansionTile(
      / / theme
      leading: Icon(
        Icons.colorize,
        color: Colors.blue,
      ),
      title: Text(
        'Color theme',
        style: TextStyle(color: Colors.blue),
      ),
      initiallyExpanded: true,
      trailing: Icon(
        Icons.expand_more,
        color: Colors.blue,
      ),
       // Close the listener
       onExpansionChanged: (v){
        Toast.toast(context,msg: v.toString());
       },
      children: <Widget>[
        Padding(
          padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
          // Set the color layout
          child: initWrap(),
        )
      ],
    );
  }

Wrap initWrap(a) {
    return Wrap(
          spacing: 8,
          runSpacing: 8,
          children: EntityState.themeColorMap.keys.map((key) {
            Color value = EntityState.themeColorMap[key];
            return InkWell(
              onTap: () {
                // Provider.of<AppInfoProvider>(context, listen: false)
                // .setTheme(key);
                setState(() {
                  // Save the default color
                  EntityState.ThemeColor = EntityState.themeColorMap[key];

                  _colorKey = key;
                });
              },
              child: Container(
                width: 40,
                height: 40,
                color: value,
                child: _colorKey == key
                    ? Icon(
                        Icons.done,
                        color: Colors.white,
                      )
                    : null,),); }).toList(), ); }Copy the code

Constant helper classes:

EntityState class:

/* * @classname entaty_state * author: SZJ * Time: CSDN:https://blog.csdn.net/weixin_44819566 2020/12/26 but * * public: getting rich * / code
class EntityState{

  SP Saves the current night mode. True Night mode. False Day mode
  static final  String  SpNight = "isNight";

  // The current theme color defaults to blue
  static Color ThemeColor  = Colors.blue;

  // Theme color
  static Map<String, Color> themeColorMap = {
    'gray': Colors.grey,
    'blue': Colors.blue,
    'blueAccent': Colors.blueAccent,
    'cyan': Colors.cyan,
    'deepPurple': Colors.purple,
    'deepPurpleAccent': Colors.deepPurpleAccent,
    'deepOrange': Colors.orange,
    'green': Colors.green,
    'indigo': Colors.indigo,
    'indigoAccent': Colors.indigoAccent,
    'orange': Colors.orange,
    'purple': Colors.purple,
    'pink': Colors.pink,
    'red': Colors.red,
    'teal': Colors.teal,
    'black': Colors.black,
  };

  static Map<String , Brightness> brightnessColorMap = {
    'dark': Brightness.dark,
    'light': Brightness.light,
  };
}
Copy the code

This part of the code is also relatively simple, above I have listed each parameter is what to do, you try to know ~

Come kangkang effect:

(Effect drawing (1.3):

Provider Global Controller

Add dependency :provider: ^4.3.2+3

The first step:

Wrap the MaterialApp() with the MultiProvider;

runApp(
    // Use MultiProvider to manage multiple states. Use provider. value for a single state
    MultiProvider(
      // Global state management
      providers: [ChangeNotifierProvider.value(value: AppInfoProvider())],

      // ignore: missing_required_param
      child: Consumer<AppInfoProvider>(
        builder: (context, appInfo, child) {
          
          return_initMaterialApp(appInfo); },),),);// Initialize MaterialApp
MaterialApp _initMaterialApp(AppInfoProvider appInfo) {
  return MaterialApp(
    // // Bubble animation
    home: snowflake_landing_page(),
    theme: ThemeData(
      // Theme mode
      primaryColor: EntityState.themeColorMap[appInfo.themeColor],
      // Night mode
      brightness: EntityState.brightnessColorMap[appInfo.themeMode],
    ),

    // Cancel the Debug flag
    debugShowCheckedModeBanner: false,); }Copy the code

Theme in the MaterialApp is set to the current theme;

  • PrimaryColor sets the current theme color

  • Brightness is the mode to set the current theme

    • Brightness. Dark night mode
    • Brightness. Light Daytime mode

My MaterialApp animation is written in runApp, so my code is written like this.

Second, create a common setting method

class AppInfoProvider with ChangeNotifier {
  // Theme color
  String _themeColor = ' ';

  // Theme mode day/night
  String _themeMode = ' ';

  String get themeColor => _themeColor;
  
  String get themeMode => _themeMode;
  
  // Set the theme color
  setTheme(String themeColor) {
    _themeColor = themeColor;
    notifyListeners();
  }
  /// Set the night modesetNight(String mode) { _themeMode = mode; notifyListeners(); }}Copy the code

The third step is to call back the current state when night mode is clicked

  // Night mode
  SwitchListTile initSwitchListTile(BuildContext context) {
    return SwitchListTile(
       ......
      onChanged: (bool value) {
        setState(() {
          isNight = value;
          // Change the theme mode
          Provider.of<AppInfoProvider>(context, listen: false)
              .setNight(value ? "dark" : "light");
        });
      },
      value: isNight,
    );
  }
Copy the code

(Flow Chart 2.1):

  • Red arrow: Indicates whether the MultiProvider is currently selected by value, whether it is selected at night, and whether it is not, and sends it to AppInfoProvider(), notifyListeners are reminded of the MultiProvider process. ) to obtain the passed value through the get method, and finally set the current mode in the MaterialApp()
  • Blue arrow: identifies the refresh method

Rendering (1.4) :

Color motifs and theme patterns work the same way

// Color theme
  Widget initExpansionTile(a) {
    return ExpansionTile(
      .....
      children: <Widget>[
        Padding(
          padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
          // Set the color layout
          child: initWrap(),
        )
      ],
    );
  }

  Wrap initWrap(a) {
    return Wrap(
  			  .....
          children: EntityState.themeColorMap.keys.map((key) {
            Color value = EntityState.themeColorMap[key];
            return InkWell(
              onTap: () {
                Provider.of<AppInfoProvider>(context, listen: false)
                    .setTheme(key);
                setState(() {
                  // Save the default colorEntityState.ThemeColor = EntityState.themeColorMap[key]; . }); },...) ; }).toList(), ); }Copy the code

The process is the same as the theme above, I will write the same code.

Rendering (1.5) :



When clicking on the color theme, we pass:

 // Save the default color
 EntityState.ThemeColor = EntityState.themeColorMap[key];
Copy the code

Saves the color of the current click

Reasons to save current color:

Some components do not change with the theme color, if necessary directly

 EntityState.ThemeColor
Copy the code

To set to follow the theme color change.

Such as:

Complete the project

Start the class: mai. Dart

Theme: setting_widget. Dart

The global control class :providers.dart

Flutter directory

Original is not easy, your praise is the biggest support for me, a praise to encourage it ~