鍵/值資料儲存


對於一些設定相關的資訊,若要以鍵/值方式儲存,可以透過 shared_preferences,在撰寫文件的這個時間點,最新版本是 0.5.8,為了使用這個套件,在 pubspec.yaml 的 dependencies 區段加入:

dependencies:
  shared_preferences: ^0.5.8

接著使用 flutter packages get 取得套件,就可以 import

import 'package:shared_preferences/shared_preferences.dart'; 

shared_preferences 非常簡單,首先要取得 SharedPreferences 實例:

SharedPreferences prefs = await SharedPreferences.getInstance();

SharedPreferences 提到了 setBoolsetDoublesetIntsetStringsetStringList 等方法,可以用來設定鍵/值,鍵的部份都只能指定字串,而相對應的以鍵取值,提供了 getBoolgetDoublegetIntgetStringgetStringList 等方法,若要移除資料,可以使用 remove

如果要取得全部的鍵,可以透過 getKeys,這會傳回 Set<String>,若要取得全部的值,必須自行實作,例如:

SharedPreferences prefs = await SharedPreferences.getInstance();
var values = prefs.getKeys().map((key) => prefs.getString(key)).toList();

底下這個範例是個簡單應用,可以在輸入各個欄位資訊後按「儲存」,這會透過
SharedPreferences 來設定鍵/值,接著在另一個頁面,透過 SharedPreferences 來取得資料並顯示出來:

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

void main() => runApp(
  MaterialApp(
    home: Scaffold(
      appBar: AppBar(title: Text('Openhome.cc')),
      body: AccountSettings(),
    )
  )
);

class AccountSettings extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _AccountSettings();
}

class _AccountSettings extends State<AccountSettings> {
  final name = TextEditingController();
  final email = TextEditingController();
  final web = TextEditingController();

  @override
  void dispose() {
    name.dispose();
    email.dispose();
    web.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
        child: Column(
          children: [
            TextField(
              decoration: InputDecoration(
                  labelText: '姓名',
                  prefixIcon: Icon(Icons.person)
              ),
              controller: name,
            ),
            TextField(
              decoration: InputDecoration(
                labelText: '電郵',
                prefixIcon: Icon(Icons.email),
              ),
              controller: email,
            ),
            TextField(
              decoration: InputDecoration(
                labelText: '網站',
                prefixIcon: Icon(Icons.web),
              ),
              controller: web,
            ),
            FlatButton(
              child: Text('儲存'),
              onPressed: () async {

                // 透過 SharedPreferences 設定鍵/值
                SharedPreferences prefs = await SharedPreferences.getInstance();

                prefs.setString('name', name.text);
                prefs.setString('email', email.text);
                prefs.setString('web', web.text);

                Navigator.push(context,
                    MaterialPageRoute(builder: (_) => InfoPage())
                );
              },
            )
          ],
        )
    );
  }
}

class InfoPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _InfoPage();
}

class _InfoPage extends State<InfoPage> {
  var name = '';
  var email = '';
  var web = '';

  final decoration = BoxDecoration(
    color: Colors.yellow,
    borderRadius: BorderRadius.circular(3.0),
    boxShadow: [
      BoxShadow(
        color:Colors.black54,
        offset: Offset(2.0,2.0),
        blurRadius: 4.0
      )
    ]
  );

  final padding = EdgeInsets.symmetric(horizontal: 40.0, vertical: 18.0);

  Widget decoratedText(String text) {
    return ListTile(
      title: DecoratedBox(
        child: Padding(
          child: Text(text),
          padding: padding,
        ),
        decoration: decoration,
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    _loadInfo();
  }

  _loadInfo() async {
    // 透過 SharedPreferences 取得鍵/值
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      name = prefs.getString('name');
      email = prefs.getString('email');
      web = prefs.getString('web');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Openhome.cc')),
      body: SingleChildScrollView(
        child: ListBody(
            mainAxis: Axis.vertical,
            children: [
              decoratedText('姓名:${name}'),
              decoratedText('電郵:${email}'),
              decoratedText('網站:${web}')
            ]
        ),
      )
    );
  }
}