flutter 学习笔记(六):持久化存储

337 阅读2分钟

在 Flutter 应用中,有时我们需要将数据保存到设备的本地存储中,以便在应用重启后能够恢复这些数据。在这篇文章中,我们将介绍如何在 Flutter 中使用持久化存储

安装

shared_preferences 包提供了一种简单的方法来实现这一功能,它是一个用于存储简单键值对的包,最新版本可以在 pub.dev 中查看

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.3.4

代码

我们创建一个页面,其中包含一个输入框和一个按钮。输入框的默认内容是从本地存储中拿的,支持编辑,当用户输入数据并点击保存按钮时,数据将保存到本地存储中,并在页面中显示

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

class PersistentStoragePage extends StatefulWidget {
  const PersistentStoragePage({super.key});
  @override
  PersistentStoragePageState createState() => PersistentStoragePageState();
}

class PersistentStoragePageState extends State<PersistentStoragePage> {
  final TextEditingController _controller = TextEditingController();
  String? _storedData;
  @override
  void initState() {
    super.initState();
    _loadData();
  }

  Future<void> _loadData() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      _storedData = prefs.getString('storedData') ?? '';
      _controller.text = _storedData!;
    });
  }

  Future<void> _saveData() async {
    final prefs = await SharedPreferences.getInstance();
    final success = await prefs.setString('storedData', _controller.text);
    if (success) {
      setState(() {
        _storedData = _controller.text;
      });
    }
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
            content: Text(
                success ? 'Data saved successfully!' : 'Failed to save data.')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Persistent Storage Page'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TextField(
              controller: _controller,
              decoration: const InputDecoration(labelText: 'Enter data'),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _saveData,
              child: const Text('Save'),
            ),
            const SizedBox(height: 20),
            Text('Stored Data: $_storedData'),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

上述的代码了,存储了一个以 storedData 为 key 名的变量,使用 setStringgetString 进行存取,很经典的用法,与 localStorage 和 react-native 的 AsyncStorage 基本一致

对比

上述的演示中我们使用的是 字符串 ( String ) ;但值得注意的是,shared_preferences 不只支持存储字符串,还支持

  • 布尔值 ( bool )

  • 整数 ( int )

  • 双精度浮点数 ( double )

  • 字符串列表 ( List<String> )

与同样跨平台的 react-native 常用的 @react-native-async-storage/async-storage 做对比,其只支持存储字符串;事实上,Android 的 SharedPreferences 和 iOS 的 NSUserDefaults 本身就支持存储非字符串的数据,很显然,flutter 的包可以减少序列化和反序列化的工作,性能上也有一定的优势