Flutter 數(shù)據(jù)存儲

最近開始著手做Flutter的項目呢堰,研究了一下Flutter的數(shù)據(jù)存儲株依。
Flutter支持PreferencesShared PreferencesNSUserDefaults) 读跷、文件和Sqflite。使用時需要引入官方倉庫的一些相應(yīng)依賴,下面詳細介紹這三種存儲方式的使用方法。

一蝌麸、Preferences:(相當(dāng)于iOS的NSUserDefaults和Android的SharedPreferences

依賴導(dǎo)入步驟:

1)在pubspec.yaml文件下添加:

 # 添加sharedPreference依賴
 shared_preferences: ^0.5.0

2)點擊pubspec.yaml文件右上角的“Packages get”按鈕或者在當(dāng)前pubspec.yaml文件目錄下在終端中輸入“flutter packages get”來同步該依賴。

3)在使用的Dart文件中引入依賴的頭文件即可使用:

import 'package:shared_preferences/shared_preferences.dart';
pubspec.yaml文件中添加依賴方式如下圖:
添加依賴

直接上代碼:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

// 創(chuàng)建一個新路由
class shared_preferences_Route extends StatefulWidget {
  @override // 重寫
  State<StatefulWidget> createState() => StorageState();
}

class StorageState extends State {
  var _textFieldController = new TextEditingController();
  var _storageString = '';
  final STORAGE_KEY = 'storage_key';

  /**
   * 利用SharedPreferences存儲數(shù)據(jù)
   */
  Future saveString() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    sharedPreferences.setString(
        STORAGE_KEY, _textFieldController.value.text.toString());
  }

  /**
   * 獲取存在SharedPreferences中的數(shù)據(jù)
   */
  Future getString() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    setState(() {
      _storageString = sharedPreferences.get(STORAGE_KEY);
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Shared Preferences存儲'),
      ),
      body: new Column(
        children: <Widget>[
          Text("請輸入文本", textAlign: TextAlign.center),
          TextField(
            controller: _textFieldController,
          ),
          MaterialButton(
            onPressed: saveString,
            child: new Text("存儲"),
            color: Colors.pink,
          ),
          MaterialButton(
            onPressed: getString,
            child: new Text("獲取"),
            color: Colors.lightGreen,
          ),
          Text('shared_preferences存儲的值為  $_storageString'),


        ],
      ),
    );
  }
}

plist文件中存儲的數(shù)據(jù)如下圖:

plist文件路徑

存儲內(nèi)容展示:

preferences存儲

二艾疟、文件存儲:

文件存儲依賴導(dǎo)入方式和Preferences的依賴導(dǎo)入是一樣的来吩。依賴如下:

# 添加文件依賴
path_provider: ^0.5.0

在 Flutter 里實現(xiàn)文件讀寫,需要使用 path_providerdartio 模塊蔽莱。path_provider 負責(zé)查找iOS/Android 的目錄文件弟疆,IO 模塊負責(zé)對文件進行讀寫。引用的頭文件如下:

import 'package:path_provider/path_provider.dart';
import 'dart:io';
path_provider中有三個獲取文件路徑的方法:
  • getTemporaryDirectory() //獲取應(yīng)用緩存目錄盗冷,等同iOS的NSTemporaryDirectory()和Android的getCacheDir() 方法怠苔。
  • getApplicationDocumentsDirectory() //獲取應(yīng)用文件目錄類似于iOS的NSDocumentDirectory和Android上的 AppData目錄。
  • getExternalStorageDirectory() //這個是存儲卡仪糖,僅僅在Android平臺可以使用嘀略。

直接上代碼:

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';

// 創(chuàng)建一個新路由
class file_Route extends StatefulWidget {
  @override // 重寫
  State<StatefulWidget> createState() => StorageState();
}

class StorageState extends State {
  var _textFieldController = new TextEditingController();
  var _storageString = '';

  /**
   * 利用文件存儲數(shù)據(jù)
   */
  saveString() async {
    final file = await getFile('file.text');
    //寫入字符串
    file.writeAsString(_textFieldController.value.text.toString());
  }

  /**
   * 獲取存在文件中的數(shù)據(jù)
   */
  Future getString() async {
    final file = await getFile('file.text');
    var filePath  = file.path;
    setState(() {
      file.readAsString().then((String value) {
        _storageString = value +'\n文件存儲路徑:'+filePath;
      });
    });
  }

  /**
   * 初始化文件路徑
   */
  Future<File> getFile(String fileName) async {
    //獲取應(yīng)用文件目錄類似于Ios的NSDocumentDirectory和Android上的 AppData目錄
    final fileDirectory = await getApplicationDocumentsDirectory();

    //獲取存儲路徑
    final filePath = fileDirectory.path;

    //或者file對象(操作文件記得導(dǎo)入import 'dart:io')
    return new File(filePath + "/"+fileName);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('文件存儲'),
      ),
      body: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text("文件存儲", textAlign: TextAlign.center),
          TextField(
            controller: _textFieldController,
          ),
          MaterialButton(
            onPressed: saveString,
            child: new Text("存儲"),
            color: Colors.cyan,
          ),
          MaterialButton(
            onPressed: getString,
            child: new Text("獲取"),
            color: Colors.deepOrange,
          ),
          Text('從文件存儲中獲取的值為  $_storageString'),
        ],
      ),
    );
  }
}

存儲內(nèi)容展示:

文件存儲

三、Sqflite 數(shù)據(jù)庫存儲

官方說明:

SQLite plugin for Flutter. Supports both iOS and Android.

 Support transactions and batches
 Automatic version managment during open
 Helpers for insert/query/update/delete queries
 DB operation executed in a background thread on iOS and Android

意思是:Sqflite是一個同時支持Android跟iOS平臺的數(shù)據(jù)庫乓诽,并且支持標(biāo)準的CURD操作。
使用時同樣需要引入依賴:

#添加Sqflite依賴
sqflite: ^1.0.0

引入頭文件:

import 'package:sqflite/sqflite.dart';

簡單使用代碼如下:

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';

class Sqflite_Route extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => StorageState();
}

class StorageState extends State {
  var _textFieldController = new TextEditingController();
  var _storageString = '';

  /**
   * 利用Sqflite數(shù)據(jù)庫存儲數(shù)據(jù)
   */
  saveString() async {
    final db = await getDataBase('my_db.db');
    //寫入字符串
    db.transaction((trx) {
      trx.rawInsert(
          'INSERT INTO user(name) VALUES("${_textFieldController.value.text.toString()}")');
    });
  }

  /**
   * 獲取存在Sqflite數(shù)據(jù)庫中的數(shù)據(jù)
   */
  Future getString() async {
    final db = await getDataBase('my_db.db');
    var dbPath = db.path;
    setState(() {
      db.rawQuery('SELECT * FROM user').then((List<Map> lists) {
        print('----------------$lists');
        var listSize = lists.length;
        //獲取數(shù)據(jù)庫中的最后一條數(shù)據(jù)
        _storageString = lists[listSize - 1]['name'] +
            "\n現(xiàn)在數(shù)據(jù)庫中一共有${listSize}條數(shù)據(jù)" +
            "\n數(shù)據(jù)庫的存儲路徑為${dbPath}";
      });
    });
  }

  /**
   * 初始化數(shù)據(jù)庫存儲路徑
   */
  Future<Database> getDataBase(String dbName) async {
    //獲取應(yīng)用文件目錄類似于Ios的NSDocumentDirectory和Android上的 AppData目錄
    final fileDirectory = await getApplicationDocumentsDirectory();

    //獲取存儲路徑
    final dbPath = fileDirectory.path;

    //構(gòu)建數(shù)據(jù)庫對象
    Database database = await openDatabase(dbPath + "/" + dbName, version: 1,
        onCreate: (Database db, int version) async {
          await db.execute("CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT)");
        });

    return database;
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('數(shù)據(jù)存儲'),
      ),
      body: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text("Sqflite數(shù)據(jù)庫存儲", textAlign: TextAlign.center),
          TextField(
            controller: _textFieldController,
          ),
          MaterialButton(
            onPressed: saveString,
            child: new Text("存儲"),
            color: Colors.cyan,
          ),
          MaterialButton(
            onPressed: getString,
            child: new Text("獲取"),
            color: Colors.deepOrange,
          ),
          Text('從Sqflite數(shù)據(jù)庫中獲取的值為  $_storageString'),
        ],
      ),
    );
  }
}

數(shù)據(jù)庫展示:

sqflite數(shù)據(jù)庫存儲

其他方法:創(chuàng)建數(shù)據(jù)庫咒程、增刪改查等方法如下:

// 獲取數(shù)據(jù)庫文件的存儲路徑
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'demo.db');

// 創(chuàng)建數(shù)據(jù)庫表
db = await openDatabase(path, version: 1,
       onCreate: (Database db, int version) async {
   await db.execute('''
        CREATE TABLE $tableBook (
            $columnId INTEGER PRIMARY KEY, 
            $columnName TEXT, 
            $columnAuthor TEXT, 
            $columnPrice REAL, 
            $columnPublishingHouse TEXT)
          ''');
    });

// 插入數(shù)據(jù)
Future<int> rawInsert(String sql, [List<dynamic> arguments]);

Future<int> insert(String table, Map<String, dynamic> values,
      {String nullColumnHack, ConflictAlgorithm conflictAlgorithm});


// 查詢數(shù)據(jù)
Future<List<Map<String, dynamic>>> rawQuery(String sql,
      [List<dynamic> arguments]);

Future<List<Map<String, dynamic>>> query(String table,
      {bool distinct,
      List<String> columns,
      String where,
      List<dynamic> whereArgs,
      String groupBy,
      String having,
      String orderBy,
      int limit,
      int offset});

// 更新數(shù)據(jù)
Future<int> rawUpdate(String sql, [List<dynamic> arguments]);

Future<int> update(String table, Map<String, dynamic> values,
      {String where,
      List<dynamic> whereArgs,
      ConflictAlgorithm conflictAlgorithm});

// 刪除
Future<int> rawDelete(String sql, [List<dynamic> arguments]);

Future<int> delete(String table, {String where, List<dynamic> whereArgs});

// 關(guān)閉數(shù)據(jù)庫
Future close() async => db.close();

以上就是三種存儲方式的簡單使用鸠天。

下面貼一下pubspec.yaml文件中依賴包的代碼:
name: wxq_flutter
description: A new Flutter application.

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  #添加新的依賴
  english_words: ^3.1.3

  # 添加sharedPreference依賴
  shared_preferences: ^0.5.0

  # 添加文件依賴
  path_provider: ^0.5.0

  #添加Sqflite依賴
  sqflite: ^1.0.0

   # 引入本地資源圖片
#  assets:
#    - images/pintuan.png

dev_dependencies:
  flutter_test:
    sdk: flutter


# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #  - images/a_dot_burr.jpeg
  #  - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware.

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

參考:
Flutter 數(shù)據(jù)存儲
Flutter 本地存儲
Flutter持久化存儲之?dāng)?shù)據(jù)庫存儲

Demo地址:Flutter 數(shù)據(jù)存儲

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市帐姻,隨后出現(xiàn)的幾起案子稠集,更是在濱河造成了極大的恐慌,老刑警劉巖饥瓷,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剥纷,死亡現(xiàn)場離奇詭異,居然都是意外死亡呢铆,警方通過查閱死者的電腦和手機晦鞋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棺克,“玉大人悠垛,你說我怎么就攤上這事∧纫辏” “怎么了确买?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長纱皆。 經(jīng)常有香客問我湾趾,道長芭商,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任搀缠,我火速辦了婚禮铛楣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胡嘿。我一直安慰自己蛉艾,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布衷敌。 她就那樣靜靜地躺著勿侯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缴罗。 梳的紋絲不亂的頭發(fā)上组橄,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音套硼,去河邊找鬼河咽。 笑死,一個胖子當(dāng)著我的面吹牛舌界,可吹牛的內(nèi)容都是我干的掘譬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼呻拌,長吁一口氣:“原來是場噩夢啊……” “哼葱轩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起藐握,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤靴拱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后猾普,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袜炕,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年初家,在試婚紗的時候發(fā)現(xiàn)自己被綠了偎窘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡笤成,死狀恐怖评架,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情炕泳,我是刑警寧澤纵诞,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站培遵,受9級特大地震影響浙芙,放射性物質(zhì)發(fā)生泄漏登刺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一嗡呼、第九天 我趴在偏房一處隱蔽的房頂上張望纸俭。 院中可真熱鬧,春花似錦南窗、人聲如沸揍很。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窒悔。三九已至,卻和暖如春敌买,著一層夾襖步出監(jiān)牢的瞬間简珠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工虹钮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留聋庵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓芙粱,卻偏偏與公主長得像祭玉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子春畔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容