preface

In previous chapters we covered the basics of Flutter. By learning from the previous chapters you were able to do some simple UI drawing and handle some simple user interactions with Flutter. As you may have noticed, What we have learned in previous chapters does not involve data storage operations, or we do not yet know how or where data should be stored in Flutter. In this blog post, I will try to solve this puzzle for you.

About data storage in Flutter

In native Android, we will write some lightweight data (such as user information, APP configuration information, etc.) into SharedPreferences for storage, and write the data that needs long-term storage into local files or Sqlite3. Of course, Flutter also uses a complete local data storage system. Let’s take a look at the three local storage methods mentioned above.

1.SharedPreferences

There is no built-in SharedPreferences store in Flutter itself, but there are third-party components available to implement this store. Yaml can be introduced via the pubspec.yaml file. The use of Pubspec. yaml is described in the Image Widget on the introduction to Flutter.

< span style = “font-size: 14px! Important; color: # 0000px; font-size: 14px! Important;”

Shared_preferences: ^0.5.0 dev_dependencies: flutter_test: Image assets: -images /a.png - images/aaa.pngCopy the code

Then run the flutter Packages get command to synchronize remote dependencies locally. At the time of writing, the latest version of sharedPreference is 0.5.0. Readers can obtain the latest version at pub.dartlang.org/flutter. You can also find other resource dependency packages that need to be imported.

The author’s words

Finally, the long and tedious preparation work is finished, mainly today’s course involves package dependency management, may be a little confused for some beginners, so I use sharedPreference to introduce dependency nonsense, if the reader has mastered the above operation, can skip the preparation work directly to the following part.

So let’s go ahead and do a little bit of share preference, and post a picture and relax.

In the figure above, we can see that we’re using sharedPreference to do a simple store and fetch operation, and that’s really all sharedPreference is, it’s either store or fetch. The reader must not forget to import the package of sharedPreference when working on it himself

import 'package:shared_preferences/shared_preferences.dart';
Copy the code

Save the data

Just like native Android, the sp operation on Flutter accesses data via key-value

/** * Use SharedPreferences to store data */
  Future saveString(a) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    sharedPreferences.setString(
        STORAGE_KEY, _textFieldController.value.text.toString());
  }
Copy the code

SharedPreferences provides access to String, bool, Double, Int, and StringList data types.

Take the data

/** * Get data in SharedPreferences */
  Future getString(a) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    setState(() {
      _storageString = sharedPreferences.get(STORAGE_KEY);
    });
  }
Copy the code

In the above operation logic, we get the value in the TextField by _textFieldController. When we press the save button, we write the data to sp. When we press the get value, we use setState to synchronize the value from SP to the following Text display.

Complete code:

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

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

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

  /** * Use SharedPreferences to store data */
  Future saveString(a) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    sharedPreferences.setString(
        STORAGE_KEY, _textFieldController.value.text.toString());
  }

  /** * Get data in SharedPreferences */
  Future getString(a) 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('Data store'),
      ),
      body: new Column(
        children: <Widget>[
          Text("Shared_preferences storage", textAlign: TextAlign.center),
          TextField(
            controller: _textFieldController,
          ),
          MaterialButton(
            onPressed: saveString,
            child: new Text("Storage"),
            color: Colors.pink,
          ),
          MaterialButton(
            onPressed: getString,
            child: new Text("Get"),
            color: Colors.lightGreen,
          ),
          Text('ShareD_preferences store value $_storageString'),,),); }}Copy the code

2. File storage

Although we are going to talk about how to store data for Flutter today, it is embarrassing that Flutter itself does not have any of the three storage methods mentioned. Fortunately, there are three libraries that support Flutter, and we do not know if this will be improved in future releases of Flutter. Manipulating files also needs to be introduced in pubspec.yaml like SharedPreferences. To read and write files in Flutter, use the PATH_Provider and DART IO modules. Path_provider searches for iOS/Android directory files, and the I/O module reads and writes files

# Add file dependency path_Provider: ^0.5.0Copy the code

The latest version I’ve introduced here is 0.5.0, which is available at pub.dartlang.org/flutter.

Because the whole operation demonstration logic with SharedPreferences, I will not explain in detail the specific operation of file storage on access to data, a little I paste the source code, the reader can refer to the code comparison, about the file storage three methods to obtain the file path I explain here, This may be familiar to readers who have done native Android development, but it may not be familiar to ios or beginners, so I thought I’d bring it up and explain.

There are three ways to get a file path in path_Provider:

  • GetTemporaryDirectory ()// Get the application cache directory, equivalent to the IOS NSTemporaryDirectory() and Android getCacheDir() methods
  • GetApplicationDocumentsDirectory () to obtain application file directory NSDocumentDirectory similar to Ios and Android AppData directory
  • External.getexternalstoragedirectory () / / this is a memory card, only can use the Android platform

Take a look at the effect of the operation file:

The SharedPreferences store logic is used, but the stored code is stored in file.text. There are detailed comments in the code, I will not explain, readers can try to compare the difference with SharedPreferences

The sample code

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

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

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

  /** * Use file to store data */
  saveString() async {
    final file = await getFile('file.text');
    // Write a string
    file.writeAsString(_textFieldController.value.text.toString());
  }

  /** * get the data in the file */
  Future getString(a) async {
    final file = await getFile('file.text');
    var filePath  = file.path;
    setState(() {
      file.readAsString().then((String value) {
        _storageString = value +'\n File storage path: '+filePath;
      });
    });
  }

  /** * Initialize the file path */
  Future<File> getFile(String fileName) async {
    // Get the application file directory similar to NSDocumentDirectory on Ios and AppData directory on Android
    final fileDirectory = await getApplicationDocumentsDirectory(a);

    // Get the storage path
    final filePath = fileDirectory.path;

    Dart: IO '// file object
    return new File(filePath + "/"+fileName);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Data store'),
      ),
      body: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text("File Storage", textAlign: TextAlign.center),
          TextField(
            controller: _textFieldController,
          ),
          MaterialButton(
            onPressed: saveString,
            child: new Text("Storage"),
            color: Colors.cyan,
          ),
          MaterialButton(
            onPressed: getString,
            child: new Text("Get"),
            color: Colors.deepOrange,
          ),
          Text('$_storageString obtained from file store'),,),); }}Copy the code

3.Sqflite

The database in Flutter is called Sqflite, unlike the native Android Sqlite. Let’s take a look at the official explanation of Sqflite:

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
Copy the code

From the above description, we know that Sqflite is a database that supports both Android and Ios platforms, and supports standard CURD operations. Let’s use the above operation files and SP code logic to experience Sqflite.

Also introduce dependencies:

# add Sqflite dependency Sqflite: ^1.0.0Copy the code

Simulation scenario:

Select * from Sqflite; select * from Sqflite; select * from Sqflite; select * from Sqflite; select * from Sqflite; The last data in the database is displayed on the following Text, and the number of data in the current database is displayed, as well as the storage path of the database.

rendering

The above describes the style code

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

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

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

  /** * Use Sqflite database to store data */
  saveString() async {
    final db = await getDataBase('my_db.db');
    // Write a string
    db.transaction((trx) {
      trx.rawInsert(
          'INSERT INTO user(name) VALUES("${_textFieldController.value.text.toString()}")');
    });
  }

  /** * Get data from the Sqflite database */
  Future getString(a) 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;
        // Get the last data in the database
        _storageString = lists[listSize - 1] ['name'] +
            ${listSize} ${listSize} ${listSize} +
            ${dbPath} = ${dbPath};
      });
    });
  }

  /** * Initialize the database storage path */
  Future<Database> getDataBase(String dbName) async {
    // Get the application file directory similar to NSDocumentDirectory on Ios and AppData directory on Android
    final fileDirectory = await getApplicationDocumentsDirectory(a);

    // Get the storage path
    final dbPath = fileDirectory.path;

    // Build the database object
    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('Data store'),
      ),
      body: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text("Sqflite database storage", textAlign: TextAlign.center),
          TextField(
            controller: _textFieldController,
          ),
          MaterialButton(
            onPressed: saveString,
            child: new Text("Storage"),
            color: Colors.cyan,
          ),
          MaterialButton(
            onPressed: getString,
            child: new Text("Get"),
            color: Colors.deepOrange,
          ),
          Text('Fetch $_storageString from Sqflite database'),,),); }}Copy the code

This is all about local storage of Flutter. In this article, I reuse the same storage business logic and UI in order to make the code structure and business logic clear. Readers can compare the details of the three storage modes with the code.