【问题标题】:How to store theme in shared preferences in flutter如何在颤动中将主题存储在共享首选项中
【发布时间】:2020-01-21 13:03:02
【问题描述】:

在这里我有一个屏幕,当我按下按钮时,我有一些按钮,它会改变应用程序的颜色,但当我重新启动应用程序时它会重置。我希望它不会重置,直到我从应用程序更改颜色。因此,为此,我想将 THEmedata 存储在共享首选项中,并且我想从共享首选项中获取主题数据,因此每当我重新启动应用程序时,它都需要从共享首选项中获取主题。

这是我尝试过的一些代码,

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

【问题讨论】:

  • 可以序列化/反序列化为json

标签: flutter dart colors themes sharedpreferences


【解决方案1】:

您可以简单地保存/检索一个主题 ID,该 ID 可用于识别启动应用程序时选择的主题,例如

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&lt;SharedPreferences&gt;

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");

【讨论】:

  • 我如何存储主题 ID?以及从哪里获得主题 ID?
  • 您可以定义自己的主题ID,例如ID:1 =>主题1等。
  • @RutvikGumasana 我编辑了我的答案,这可以让你开始
  • 非常感谢,我会试试代码并告诉你:)
  • @SlahLayouni 您好,我对您的解决方案有疑问。如何同步加载 SharedPreferences?我有同样的问题,我想从 sharedpreferences 加载语言和主题并将其保存在 initialState 中。谢谢!
【解决方案2】:
// Your 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,
  ),
};

开始吧

共享首选项

// shared_prefs.dart
class SharedPrefs {
  static late SharedPreferences _sharedPrefs;

  factory SharedPrefs() => SharedPrefs._internal();

  SharedPrefs._internal();

  Future<void> init() async {
    _sharedPrefs = await SharedPreferences.getInstance();
  }

  int? get getThemeIndex => _sharedPrefs.getInt(selectedThemeIndex);

  set setThemeIndex(int? value) {
    _sharedPrefs.setInt(selectedThemeIndex, value!);  // Using selectedThemeIndex from constant
  }
}

// constants.dart
const String selectedThemeIndex = "selected_theme_index";

main.dart 文件

// main.dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SharedPrefs().init();   // Call sharedpreference class here
  return runApp(MyApp());
}

theme_bloc.dart 文件

//theme_bloc.dart
class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
  ThemeBloc() : super(ThemeState(themeData: appThemeData[AppTheme.values[SharedPrefs().getThemeIndex ?? 0]]!));

  @override
  Stream<ThemeState> mapEventToState(
    ThemeEvent event,
  ) async* {
    if (event is ThemeChanged) {
      // I am storing theme index
      SharedPrefs().setThemeIndex = event.theme.index;  // Trigger when you change the theme
      yield ThemeState(themeData: appThemeData[event.theme]!);
    }
  }
}

【讨论】:

    【解决方案3】:

    使用 ThemeProvider 提供主题数据。有一个例子。 有关详细信息,您可以从GitHub 运行此应用

    import 'package:flutter/material.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    
    ThemeData light_mode = ThemeData(
      brightness: Brightness.light,
    );
    
    ThemeData dark_mode = ThemeData(
      brightness: Brightness.dark,
    );
    
    class ThemeNotifier extends ChangeNotifier {
      final String key = "theme";
      SharedPreferences? _preferences;
      bool? _darkMode;
    
      bool? get darkMode => _darkMode;
    
      ThemeNotifier() {
        _darkMode = false;
        _loadFromPreferences();
      }
    
      _initialPreferences() async {
        _preferences ??= await SharedPreferences.getInstance();
      }
    
      _savePreferences() async {
        await _initialPreferences();
        _preferences!.setBool(key, _darkMode!);
      }
    
      _loadFromPreferences() async {
        await _initialPreferences();
        _darkMode = _preferences!.getBool(key) ?? true;
        notifyListeners();
      }
    
      toggleChangeTheme(bool isOn) {
        darkMode==isOn ? _darkMode! : _darkMode = !_darkMode!;
        _savePreferences();
        notifyListeners();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 2019-05-24
      • 1970-01-01
      • 2021-08-16
      • 1970-01-01
      • 2020-11-12
      • 1970-01-01
      相关资源
      最近更新 更多