JS中的高阶函数和偏函数

使用 MaterialAppdarkTheme 选项,可以很方便地适配跟随系统的DarkMode:

MaterialApp( 
    theme: ThemeData( 
        brightness: Brightness.light, 
        primaryColor: Colors.blue, 
    ), 
    darkTheme: ThemeData( 
        brightness: Brightness.dark, 
    ),
);

也可直接写做

darkTheme: ThemeData.dark()
  • 这种方式是自动跟随iOS/Android的系统设置来切换的,无需用户再单独设置

手动开启夜间模式

上述的跟随系统自动切换暗黑模式的体验可能并不是很好,比如用户不喜欢夜间模式或者App的夜间模式配色适配并不是很好,这就会导致用户无法手动控制app的夜间模式或者只能关闭系统的设置。因此我们可以增加手动控制以及跟随系统的选项,让用户选择是否开启以及开启的方式。

保存用户配置

在flutter中可以使用 shared_preferences 来保存用户的配置数据,具体使用方法详见: shared_preferences 使用

状态管理

主题的手动切换是影响全局的,如果通过常规的数据流向很难做到。常见的几种状态管理:

Provider 是Google I/O 2019大会宣布的现在官方推荐的状态管理方式,我们需要在设置页里面通过用户设置,把变更状态共享给其他Widget,这里采用 Provider 这种方式来实现状态共享。

通用夜间模式Provider Model类

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

class DarkModeModel with ChangeNotifier {
  /// 夜间模式 0: 关闭 1: 开启 2: 随系统
  int _darkMode;

  static const Map<int, String> darkModeMap = {
    0: "关闭",
    1: "开启",
    2: "跟随系统"
  };

  static const String STORE_KEY = 'darkMode';

  SharedPreferences _prefs;

  int get darkMode => _darkMode;

  DarkModeModel() {
    _init();
  }

  void _init() async {
    this._prefs = await SharedPreferences.getInstance();
    int localMode = this._prefs.getInt(STORE_KEY);
    changeMode(localMode ?? 0);
  }

  void changeMode(int darkMode) async {

    _darkMode = darkMode;

    notifyListeners();

    SharedPreferences prefs = this._prefs ?? SharedPreferences.getInstance();

    await prefs.setInt(STORE_KEY, darkMode);
  }
}

MaterialApp修改

如果手动控制是否开启夜间模式,可以设置 MaterialApptheme 选项为 ThemeData.dark()

theme: ThemeData.dark()

因为需要同时保留随系统自动切换与手动切换,而 darkTheme 选项和 theme 又有冲突,所以这里需要根据 darkModeModel.darkMode 的取值来渲染不同的 MaterialApp ,如果是手动模式再根据 darkModeModel.darkMode 的取值来渲染不同的 theme

MultiProvider(
  providers: [
    ChangeNotifierProvider(builder: (_) => DarkModeModel())
  ],
  child: Consumer<DarkModeModel>(
    builder: (context, darkModeModel, _) {
      return darkModeModel.darkMode == 2 
        ? MaterialApp(
            title: '特效君',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            darkTheme: ThemeData.dark(),
              home: MainPage(title: '特效君'),
            ) 
        : MaterialApp(
            title: '特效君',
            theme: darkModeModel.darkMode == 1 
              ? ThemeData.dark()
              : ThemeData(
                  primarySwatch: Colors.blue,
                ),
            home: MainPage(title: '特效君'),
          );
    },
  ),
)
我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章