1

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

主要.dart

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

主题视图模型

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();
    });
  }
...
}

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

在此处输入图像描述

如何解决?在加载主题之前,如何显示加载微调器?

4

1 回答 1

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();
    });
  }
...
}
于 2021-08-13T08:30:12.207 回答