赞
踩
三种形式:文件 SharedPreferences 数据库
文件是存储在某种介质(比如磁盘)上指定路径的、具有文件名的一组有序信息的集合。 定义文件的存储路径。
Flutter 提供了两种文件存储的目录,即临时(Temporary)目录与文档(Documents)目录、外部目录:
临时目录是操作系统可以随时清除的目录,通常被用来存放一些不重要的临时缓存数据。在 iOS 上对应着 NSTemporaryDirectory 返回的值,而在 Android 上则对应着 getCacheDir 返回的值。
文档目录则是只有在删除应用程序时才会被清除的目录,通常被用来存放应用产生的重要数据文件。在 iOS 上,对应着 NSDocumentDirectory,在 Android 上则对应着 AppData 目录。
外部存储目录:可以使用getExternalStorageDirectory()来获取外部存储目录,如SD卡;由于iOS不支持外部目录,所以在iOS下调用该方法会抛出UnsupportedError异常,而在Android下结果是android SDK中getExternalStorageDirectory的返回值。
在这里我们借助pathprovider插件来实现文件目录的创建读取写入。PathProvider 插件提供了一种平台透明的方式来访问设备文件系统上的常用位置。
1.引入PathProvider插件;在pubspec.yaml文件中添加如下声明:
path_provider: ^0.4.1
添加后,执行flutter packages get 获取一下, 版本号可能随着时间推移会发生变化,读者可以使用最新版。
2.代码实现
//创建文件目录 import 'dart:io'; import 'package:path_provider/path_provider.dart'; Future<File> get _localFile async { // getTemporaryDirectory()//临时目录 // getApplicationDocumentsDirectory()//应用程序的文档目录 // getExternalStorageDirectory()外部储存目录 final directory = await getApplicationDocumentsDirectory(); final path = directory.path; return File('$path/content.txt'); } //将字符串写入文件 Future<File> writeContent(String content) async { final file = await _localFile; return file.writeAsString(content); } //从文件读出字符串 Future<String> readContent() async { try { final file = await _localFile; String contents = await file.readAsString(); return contents; } catch (e) { return ""; } }
类似于Android的sp一样,适合少量的数据,且适合配置数据。需要借助插件shared_preferences。SharedPreferences 的使用方式非常简单方便。不过需要注意的是,以键值对的方式只能存储基本类型的数据,比如 int、double、bool 和 string。
1.添加插件,注意插件版本不要太新
shared_preferences: ^0.5.4
2.代码实现
//获取数据
Future<String> getSpContent() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String counter = (prefs.getString('content') ?? "");
return counter;
}
//设置数据
Future<void> setSPContent(String content) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('content', content);
}
flutter 也可以实现数据库的存储,数据库只适合大量数据的情况,少量数据使用文件或者sp就可以实现。这里我们使用的是sqflite插件来实现数据库的增删。如果我们需要持久化大量格式化后的数据,并且这些数据还会以较高的频率更新,为了考虑进一步的扩展性,我们通常会选用 sqlite 数据库来应对这样的场景。与文件和 SharedPreferences 相比,数据库在数据读写上可以提供更快、更灵活的解决方案。
sqflite: ^1.1.7+3
初始化数据库对象
抽象对象
abstract class DatabaseProvider { Database _instance; String get databaseName;// get方法 String get tableName; Future<Database> get database async { if (_instance == null) { var path = await getDatabasesPath(); _instance = await openDatabase( join( path, databaseName, ), onCreate: createDatabase, version: 1, ); } return _instance; } createDatabase(Database db, int version); } //子类继承父类,重写方法 class TestDatabaseProvider extends DatabaseProvider { @override String get databaseName => "test.db"; // 重写 get 方法 @override String get tableName => "user"; /** * 重写父类方法 */ @override createDatabase(Database db, int version) { db.execute( """ CREATE TABLE user( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age TEXT ); """ ); } }
调用
class _DbTestPageState extends State<DbTestPage> { var insertResult; static TestDatabaseProvider provider; String queryResult = "--"; @override void initState() { // TODO: implement initState super.initState(); // 初始化数据库对象 provider = TestDatabaseProvider(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("测试数据库的页面"), ), body: Column( mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[ Row( children: <Widget>[ Expanded( child: TextField( onChanged: (value) => _saveInsert(value), decoration: InputDecoration( hintText: "请输入int-id,String-name,String-age", prefixIcon: Icon(Icons.person)), maxLines: 1, textAlign: TextAlign.left, obscureText: false, // 隐藏正在编辑的内容 autofocus: true, ), ), RaisedButton( onPressed: () => _insertData(insertResult), child: Text("插入"), ) ], ), RaisedButton( onPressed: _queryAll, child: Text("查询所有"), ), Text(queryResult,style: TextStyle(),) , ], ), ); } _saveInsert(String value) => insertResult = value; _insertData(var insertResult) async { if (insertResult.isEmpty) { return; } List list = insertResult.split(","); UserEntity user = UserEntity(); user.id = int.parse(list[0]); user.name = list[1]; user.age = list[2]; Database database = await provider.database; await database .insert(provider.tableName, user.toJson()) .then((value) => {print("_insertData--$value")}); } void _queryAll() async { queryResult="-----\n"; Database database = await provider.database; Future<List<Map<Object, dynamic>>> future = database.query(provider.tableName); future.then((List<Map<Object, dynamic>> list) { for (Map<Object, dynamic> map in list) { for (var key in map.keys) { print("key=${key}--value=${map[key]}"); setState(() { queryResult = queryResult+"$key:${map[key]}\n" ; }); } } }); } }
效果图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。