【问题标题】:Late initialization of a Theme in FlutterFlutter 中主题的后期初始化
【发布时间】:2021-10-16 12:11:07
【问题描述】:

我正在尝试在我的 Flutter 应用中实现深色和浅色主题。为此,我使用 ViewModel 方法在主题更改时通知整个应用程序。当用户更改主题时,我使用 shared_preferences 保存它。当应用程序再次启动时,我正在从共享首选项加载保存的主题:

ma​​in.dart

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<ThemeViewModel>(
      builder: (context, themeViewModel, _) => MaterialApp(
        theme: themeViewModel.getTheme(),
        ...
  

theme_view_model

class ThemeViewModel extends ChangeNotifier {
  final darkTheme = ThemeData(...;

  final lightTheme = ThemeData(...);

  late ThemeData _themeData;

  ThemeData getTheme() => _themeData;

  ThemeViewModel() {
    StorageManager.readData('themeMode').then((value) {
      var themeMode = value ?? 'light';
      if (themeMode == 'light') {
        _themeData = lightTheme;
      } else {
        _themeData = darkTheme;
      }
      notifyListeners();
    });
  }
...
}

但是,当我启动应用程序时,我会在几秒钟内看到错误屏幕(可能在从共享首选项加载主题数据之前):

如何解决?我怎么能显示例如在加载主题之前的加载微调器?

【问题讨论】:

    标签: flutter flutter-sharedpreference lateinit


    【解决方案1】:

    有几种方法可以解决它。

    1-您可以为您的ThemeViewModel 定义一个异步初始化方法并在您的main 方法中等待它。

    void main() async {
      final viewModel = ThemeViewModel();
      await viewModel.init();
      ...
    }
    
    class ThemeViewModel extends ChangeNotifier {
      final darkTheme = ThemeData(...;
    
      final lightTheme = ThemeData(...);
    
      late ThemeData _themeData;
    
      ThemeData getTheme() => _themeData;
      
      Future init() async {
        themeMode = await StorageManager.readData('themeMode') ?? 'light';
        if (themeMode == 'light') {
          _themeData = lightTheme;
        } else {
          _themeData = darkTheme;
        }
      }
    }
    

    2-当 _themeData 为空时,您可以提供一个默认主题来使用

    class ThemeViewModel extends ChangeNotifier {
      final darkTheme = ThemeData(...;
    
      final lightTheme = ThemeData(...);
    
      ThemeData? _themeData;
    
      ThemeData getTheme() => _themeData ?? lightTheme;
    
      ThemeViewModel() {
        StorageManager.readData('themeMode').then((value) {
          var themeMode = value ?? 'light';
          if (themeMode == 'light') {
            _themeData = lightTheme;
          } else {
            _themeData = darkTheme;
          }
          notifyListeners();
        });
      }
    ...
    }
    

    【讨论】:

    • 是的,我正在考虑提供默认主题,但如果应用程序加载然后几秒钟后主题切换会很丑。我将尝试实施第一种方法。
    猜你喜欢
    • 2023-02-25
    • 2021-04-26
    • 2021-11-02
    • 1970-01-01
    • 2021-01-18
    • 2019-12-05
    • 2021-08-29
    • 2021-10-28
    • 1970-01-01
    相关资源
    最近更新 更多