Flutter 如何优雅的使用sharedpreferences

307 阅读2分钟

Flutter 如何优雅的使用sharedpreferences

简单的分享一下我日常工作对flutter shared_preferences持久化的一些简单封装使用,参考了一些开发者的经验,保证简单且实用。

1、同步处理存储和拿取(初始化后可以同步使用)

class SpHelper {
  static SpHelper? _instance;
  static late SharedPreferences prefs;
  static final Lock _lock = Lock();

  static Future<SpHelper?> init() async {
    if (_instance == null) {
      await _lock.synchronized(() async {
        // 保持本地实例直到完全初始化。
        var singleton = SpHelper();
        await singleton._init();
        _instance = singleton;
      });
    }
    return _instance;
  }

  Future _init() async {
    prefs = await SharedPreferences.getInstance();
  }

  static putStorage(String key, value) async {
    if (value is String) {
      prefs.setString(key, value);
    } else if (value is num) {
      prefs.setInt(key, value as int);
    } else if (value is double) {
      prefs.setDouble(key, value);
    } else if (value is bool) {
      prefs.setBool(key, value);
    } else if (value is List) {
      prefs.setStringList(key, value.cast<String>());
    }
  }

  // 获取
  static getStorage(String key, [dynamic replace]) {
    if (prefs == null) return;
    return prefs.get(key) ?? replace;
  }

  /// 存储 String 类型数据
  static Future<void> putString(String key, String value) async {
    await prefs.setString(key, value);
  }

  /// 获取 String 类型数据
  static String getString(String key, [String replace = '']) {
    return prefs.getString(key) ?? replace;
  }

  /// 存储 int 类型数据
  static Future<void> putInt(String key, int value) async {
    await prefs.setInt(key, value);
  }

  /// 获取 int 类型数据
  static int getInt(String key, [int replace = 0]) {
    return prefs.getInt(key) ?? replace;
  }

  /// 存储 bool 类型数据
  static Future<void> putBool(String key, bool value) async {
    await prefs.setBool(key, value);
  }

  /// 获取 bool 类型数据
  static bool getBool(String key, [bool replace = false]) {
    return prefs.getBool(key) ?? replace;
  }

  /// 获取 List<String> 类型数据
  static List<String> getStringList(String key) {
    return prefs.getStringList(key) ?? [];
  }

  static Future<void> putStringList(String key, List<String> value) async {
    await prefs.setStringList(key, value);
  }
}

需要在app初始化时加上

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 初始化SpHelper
  await SpHelper.init();

  runApp(MainApp(key: appKey,),
  );
}

使用示范

// 存储
SpHelper.putStorage("user_name", "admin");
// 获取
SpHelper.getStorage("user_name");

// 指定类型
SpHelper.putString("user_name", "admin")

SpHelper.getString("user_name")

2、进一步简化对 Shared Preferences 的存取操作(开发中十分有用)

实际开发中我们不可能需要存取的时候就新写一个SharedPreferences的key,这样不好管理,就算把所有key都放到一个地方,那获取的时候也有点麻烦,并且每次取出的时候都要确认下key。我们可以根据前面的SpHelper去简单封装下存取只需要定义一个方法。

首先创建一个属性代理类

class SpProperty<T> {
  final String key;
  final T defaultValue;

  const SpProperty(this.key, this.defaultValue);

  /// 获取值
  T get value {
    switch (T) {
      case String:
        return SpHelper.getString(key, defaultValue as String) as T;
      case int:
        return SpHelper.getInt(key, defaultValue as int) as T;
      case bool:
        return SpHelper.getBool(key, defaultValue as bool) as T;
      case List<String>:
        return SpHelper.getStringList(key) as T;
      default:
        return SpHelper.getStorage(key, defaultValue) as T;
    }
  }

  /// 设置值
  Future<void> setValue(T value) async {
    switch (T) {
      case String:
        await SpHelper.putString(key, value as String);
        break;
      case int:
        await SpHelper.putInt(key, value as int);
        break;
      case bool:
        await SpHelper.putBool(key, value as bool);
        break;
      case List<String>:
        await SpHelper.putStringList(key, value as List<String>);
        break;
      default:
        await SpHelper.putStorage(key, value);
    }
  }
}

然后定义一个share存取方法

class SettingPrefer {

  // 主题 0 跟随系统  1 白天模式 2 夜晚模式  
  static const themeModeInt = SpProperty<int>("AppThemeMode", 2);

  // 是否测试版
  static const useTest = SpProperty<bool>("use_test", false);
}

最后的简单使用

// 存
SettingPrefer.themeModeInt.setValue(1)
// 取
SettingPrefer.themeModeInt.value

大家有简单和实用的方案欢迎补充