flutter使用shared_preferences依赖库实现简单的本地数据存储,封装成一个简单的单例类,方便前端同学使用

这篇具有很好参考价值的文章主要介绍了flutter使用shared_preferences依赖库实现简单的本地数据存储,封装成一个简单的单例类,方便前端同学使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

shared_preferences 仓库地址:shared_preferences | Flutter Package

shared_preferences这个依赖库还是非常好用的,全平台支持,就像前端经常使用的localstorage一样方便,所以就想着封装成一个简单的类,方便前端同学使用。封装好的代码支持json或者数组等这种类型的存储和获取。

flutter使用shared_preferences依赖库实现简单的本地数据存储,封装成一个简单的单例类,方便前端同学使用,多端开发,前端

在utils里面新建storeage.dart,封装好的类代码是:

import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

// 封装一个本地存储的类
class Storage {
  // 静态单例模式:静态私有实例对象
  static Storage? _instance;

  // 实现工厂函数
  factory Storage() => _instance ?? Storage._init();

  /// 命名构造函数 用于初始化SharedPreferences实例对象
  Storage._init() {
    // 初始化SharedPreferences实例
    _initStorage();
  }

  // SharedPreferences对象
  static late SharedPreferences _storage;

  // 之所以这个没有写在 _init中,是因为SharedPreferences.getInstance是一个异步的方法 需要用await接收它的值
  _initStorage() async {
    try {
      _storage = await SharedPreferences.getInstance();
    } catch (e) {
      _storage = await SharedPreferences.getInstance();
    }
  }

  /// 设置存储
  setStorage(String key, dynamic value) async {
    await _initStorage();
    String type;
    // 监测value的类型 如果是Map和List,则转换成JSON,以字符串进行存储
    if (value is Map || value is List) {
      type = 'String';
      value = const JsonEncoder().convert(value);
    }
    // 否则 获取value的类型的字符串形式
    else {
      type = value.runtimeType.toString();
    }
    // 根据value不同的类型 用不同的方法进行存储
    switch (type) {
      case 'String':
        _storage.setString(key, value);
        break;
      case 'int':
        _storage.setInt(key, value);
        break;
      case 'double':
        _storage.setDouble(key, value);
        break;
      case 'bool':
        _storage.setBool(key, value);
        break;
    }
  }

  /// 获取存储 注意:返回的是一个Future对象 要么用await接收 要么在.then中接收
  Future<dynamic> getStorage(String key) async {
    await _initStorage();
    // 获取key对应的value
    dynamic value = _storage.get(key);
    // 判断value是不是一个json的字符串 是 则解码
    if (_isJson(value)) {
      return const JsonDecoder().convert(value);
    } else {
      // 不是 则直接返回
      return value;
    }
  }

  /// 是否包含某个key
  Future<bool> hasKey(String key) async {
    await _initStorage();
    return _storage.containsKey(key);
  }

  /// 删除key指向的存储 如果key存在则删除并返回true,否则返回false
  Future<bool> removeStorage(String key) async {
    await _initStorage();
    if (await hasKey(key)) {
      await _storage.remove(key);
      return true;
    } else {
      return false;
    }
    // return  _storage.remove(key);
  }

  /// 清空存储 并总是返回true
  Future<bool> clear() async {
    await _initStorage();
    _storage.clear();
    return true;
  }

  /// 获取所有的key 类型为Set<String>
  Future<Set<String>> getKeys() async {
    await _initStorage();
    return _storage.getKeys();
  }

  // 判断是否是JSON字符串
  _isJson(dynamic value) {
    try {
      // 如果value是一个json的字符串 则不会报错 返回true
      const JsonDecoder().convert(value);
      return true;
    } catch (e) {
      // 如果value不是json的字符串 则报错 进入catch 返回false
      return false;
    }
  }
}

// 导出一个全局使用的实例

// 使用的一些示例
/*
  var ps = Storage();
  // 1. 存储所有类型的值
  ps.setStorage('Map', {"key": "value"}); // 存储Map
  ps.setStorage('int', 1); // 存储int
  ps.setStorage('double', 1.0); // 存储double
  ps.setStorage('bool', true); // 存储bool
  ps.setStorage('String', "Hello World"); // 存储String
  ps.setStorage('List', [1, true, 'String', 1.0]); // 存储List
  // 除setStorage以外 获取的方法的返回值全部都是Future类型
  // 因此需要使用await获取 或者 在其.then方法中获取值
  // 2. 根据key获取存储的值
  // 2.1 通过await 直接获取存储的值 注意 await只能在async方法中使用
  Logger().i(await ps.getStorage('Map')); // {key: value}
  // 2.2 在then中获取存储的值
  ps.getStorage('String').then((value) => Logger().i(value)); // {key: value}
  // 3. 根据key移除存储的值
  Logger().i(await ps.removeStorage("List")); // true  删除成功
  Logger().i(await ps.removeStorage('nothing')); // false 删除失败
  // 4. 是否包含某个key
  Logger().i(await ps.hasKey('map')); // 存在   true
  Logger().i(await ps.hasKey("List")); // 不存在 false
  // 5. 获取所有的key
  Logger().i(await ps.getKeys());
  // 6. 清空所有存储
  Logger().i(await ps.clear()); //一直都会返回true
*/

然后到组件中或者状态管理里面使用:

flutter使用shared_preferences依赖库实现简单的本地数据存储,封装成一个简单的单例类,方便前端同学使用,多端开发,前端

然后进行状态数据存储:

  // 减少状态管理的数值
  void setName(String val) {
    name.value = val;
    storage.setStorage("name", name.value);
    update();
  }

 状态数据初始化:获取storage里面的值并设置为获取到的值文章来源地址https://www.toymoban.com/news/detail-806887.html


  // 以下为周期函数
  @override
  void onInit() {
    print('onInit');
    super.onInit();
    storage.getStorage("name").then((value) {
      print("得到的存储数据是: ${value}");
      name.value = value.toString();
    });
  }

到了这里,关于flutter使用shared_preferences依赖库实现简单的本地数据存储,封装成一个简单的单例类,方便前端同学使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter依赖注入

    依赖注入(Dependency Injection,简称DI)是一种软件设计模式,它的主要目的是将对象之间的依赖关系解耦,使得代码更加可维护、可测试、可扩展,使得代码更易于维护和测试。在Flutter中,DI可以帮助我们管理应用程序中的各种依赖关系,包括服务、数据存储和UI组件等。 在

    2024年02月08日
    浏览(25)
  • flutter获取地理定位:geolocator依赖详细用法

     本文使用geolocator插件实现app物理定位功能。 该插件的主要功能有: 获取最后已知位置; 获取设备当前位置; 获取连续的位置更新; 检查设备是否启用了定位服务; 计算两个地理坐标之间的距离(米); 计算两个地理坐标之间的方位;  方法一:在pubspec.yaml文件中添加它

    2024年01月20日
    浏览(39)
  • Flutter - 一行命令解决多个pubspec.yaml文件的依赖项问题

    项目为了模块化,创建了一堆 Package 和 Plugin ,这么做没什么问题,但是遇到Flutter SDK目录路径变化或者其他一些情况导致需要重新获取依赖项时就麻烦了。麻烦之处在于需要在每个 pubspec.yaml 文件所在的目录中运行 flutter pub get 命令,虽然也不是什么大问题,但是这种重复简

    2024年02月08日
    浏览(39)
  • Flutter:安装依赖报错doesn‘t support null safety

    项目中需要引用http依赖,在pubspec.yaml文件中添加如下信息: 当同步时,报错信息如下: [myflutter] flutter pub upgrade Resolving dependencies... The current Dart SDK version is 3.1.3. Because myflutter depends on http =0.2.8+2 0.13.0-nullsafety.0 which doesn\\\'t support null safety, version solving failed. The lower bound of \\\"sdk:

    2024年02月04日
    浏览(51)
  • 使用 Spring 实现控制反转和依赖注入

    在本文中,我们将介绍 IoC (控制反转)和 DI (依赖注入)的概念,以及如何在 Spring 框架中实现它们。 控制反转是软件工程中的一个原则,它将对象或程序的某些部分的控制权转移给容器或框架。我们最常在面向对象编程的上下文中使用它。 与传统编程相比,传统编程中我

    2024年02月13日
    浏览(35)
  • 【Flutter】Flutter 使用 fluttertoast 实现显示 Toast 消息

    【Flutter】Flutter 使用 fluttertoast 实现显示 Toast 消息 在这篇文章中,我将与你分享如何在 Flutter 项目中使用 fluttertoast 包来显示 Toast 消息。 Toast 是一个简短的、非模态的消息提示框,它可以在应用的前端显示,不会打断用户的操作。 fluttertoast 是一个非常受欢迎的 Flutter 包,用

    2024年02月06日
    浏览(38)
  • .Net Framework使用Autofac实现依赖注入

    最近也是找了快2周的工作了,收到的面试邀请也就几个,然后有个面试题目是用asp.net mvc + Entityframework 做一个学生信息增删改查系统。因为题目要求了用Entityframework 也就是EF 那也就不上core了,web项目也是用Framework 4.8去做的。 本文的重点是IOC容器,在Framework 中是没有自带的

    2024年02月09日
    浏览(45)
  • 【Flutter】Flutter 使用 table_calendar 实现自定义日历

    【Flutter】Flutter 使用 table_calendar 实现自定义日历 你好!今天我要为你介绍一个非常实用的 Flutter 日历组件—— table_calendar 。这个组件不仅功能强大、高度可定制,而且使用起来非常简单。在本文中,我会手把手教你如何使用这个组件,并分享一些实际业务中的应用示例。希

    2024年02月08日
    浏览(45)
  • 【Flutter】Flutter 使用 fluent_ui 实现 Windows UI

    当然,我们将按照你的要求分批次输出文章的正文内容。以下是前三个章节的内容: fluent_ui 是一个在 Flutter 中实现 Windows UI 的包。通过使用这个包,开发者可以轻松地在 Flutter 项目中创建出符合 Windows UI 指南的应用程序。本文将详细介绍 fluent_ui 的主要特性和使用方法,帮助

    2024年02月09日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包