Как сохранить тему в общих настройках во флаттере - PullRequest
1 голос
/ 21 января 2020

Здесь у меня есть один экран, на котором есть какая-то кнопка, когда я нажимаю кнопку, она меняет цвет приложения, но сбрасывается при перезапуске приложения. Я хочу, чтобы он не сбрасывался, пока я не изменил цвет из приложения. поэтому для этого я хочу хранить THemedata в общих настройках и получать данные темы из общих настроек, поэтому при каждом перезапуске приложения необходимо выбрать тему из общих настроек.

Вот код, который я ' пробовал,

ThemeBlo c .dart

class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
  @override
  ThemeState get initialState =>
      ThemeState(themeData: appThemeData[AppTheme.GreenLight]);

  @override
  Stream<ThemeState> mapEventToState(
    ThemeEvent event,
  ) async* {
    if (event is ThemeChanged) {
      yield ThemeState(themeData: appThemeData[event.theme]);
    }
  }
}

ThemeEvent.dart

abstract class ThemeEvent extends Equatable {
  ThemeEvent([List props = const <dynamic>[]]) : super(props);
}

class ThemeChanged extends ThemeEvent {
  final AppTheme theme;

  ThemeChanged({
    this.theme,
  }) : super([theme]);
}

ThemeState.dart

@immutable
class ThemeState extends Equatable {
  final ThemeData themeData;

  ThemeState({
    @required this.themeData,
  }) : super([themeData]);
}

AppTheme.dart

enum AppTheme {
  GreenLight,
  GreenDark,
  BlueLight,
  BlueGrey,
  Amber,
}

final appThemeData = {
  AppTheme.GreenLight: ThemeData(
    brightness: Brightness.light,
    primaryColor: Colors.teal,
  ),
  AppTheme.GreenDark: ThemeData(
    brightness: Brightness.light,
    primaryColor: Colors.orange,
  ),
};

1 Ответ

2 голосов
/ 21 января 2020

Вы можете просто сохранить / получить идентификатор темы, который можно использовать для идентификации выбранной темы при запуске приложения, например,

class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {

  // at this point you should be already have a mainSharedPreferences already initialized, could be in SplashScreen
  // to prevent async calls in the initialState

  @override
  ThemeState get initialState => ThemeState(
      themeData: appThemeData[
          MyApp.mainSharedPreferences.getInt("selectedThemeIndex") ??
              AppTheme.GreenLight]);

  @override
  Stream<ThemeState> mapEventToState(
    ThemeEvent event,
  ) async* {
    if (event is ThemeChanged) {
      await _persistTheme(event.theme);
      yield ThemeState(themeData: appThemeData[event.theme]);
    }
  }

  _persistTheme(AppTheme theme) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setInt("selectedThemeIndex", theme.index);
    // or you could save the theme.toString()
    // prefs.setString("selectedTheme", theme.toString());
  }
}

Как подготовить SharedPreferences, чтобы избежать Future<SharedPreferences>

class MyApp extends StatefulWidget {
  static SharedPreferences mainSharedPreferences;

  @override
  _MyAppState createState() => _MyAppState();
}



class _MyAppState extends State<MyApp> {

_loadApp() async {
    MyApp.mainSharedPreferences = await SharedPreferences.getInstance();
    // you can load here any other data or external data that your app might need
  }

  @override
  void initState() { 
    super.initState();
    _loadApp();
  }

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      localizationsDelegates: [
      // ...

Тогда вы можете использовать его в любом месте вашего приложения, например

// to save value
MyApp.mainSharedPreferences.setInt("selectedThemeIndex", value);

// to get the saved value
MyApp.mainSharedPreferences.getInt("selectedThemeIndex");
...