在Flutter中使用SharedPreferences来本地存储数据

4,401 阅读10分钟

可能有一天,您想在您的Flutter应用程序中持久化数据,以便您以后可以重复使用它。这种功能的一个常见用例是存储登录凭证,以便在用户下次启动应用时调用。

通过SharedPreferences,您可以配置您的Flutter应用程序,即使在用户终止活动后也能记住这些数据。sharedPreferences可用于存储关键数据,如密码、令牌和复杂的关系数据。

在本教程中,我们将演示如何在Flutter应用程序中使用SharedPreferences来持久化和修改数据。我们将通过实际例子介绍以下内容。

什么是 Flutter 中的 SharedPreferences?

SharedPreferences是Android和iOS应用程序用来在分配的空间中存储简单数据的。这些数据即使在应用程序关闭和再次启动时也存在;我们仍然可以像以前一样检索该值。

存储在SharedPreferences中的数据可以被编辑和删除。SharedPreferences将数据存储在一个键值对中。

为了在Flutter中使用SharedPreferences,一个名为 [shared_preferences](https://gist.github.com/philipszdavido/aa5086ce7f0f85e50cddd008895ae4b6)的插件使我们能够存储数据。该插件在iOS上封装了NSUserDefaults ,在Android上封装了SharedPreferences

构建Flutter项目的脚手架

让我们来看看如何搭建一个Flutter项目的脚手架,将shared_preferences 插件添加到Flutter项目中,以及该插件暴露给我们的方法。

你需要在你的机器上已经安装了一些工具和二进制文件,包括Flutter SDK和Android Studio。

Flutter SDK

要在我们的机器上安装Flutter SDK,您需要根据您的机器选择下面的Flutter二进制文件。

  • Windows
  • macOS
  • Linux
  • [Chrome OS](https://flutter.dev/docs/get-started/install/chromeos)

安装完成后,您的系统中会有全局可用的Flutter CLI。运行下面的命令来测试一下。

➜  flutter --version

Flutter 2.0.6 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 1d9032c7e1 (3 months ago) • 2021-04-29 17:37:58 -0700
Engine • revision 05e680e202
Tools • Dart 2.12.3

您的版本可能与我的不同,但您应该能够验证Flutter SDK已成功安装。

安卓工作室

我们将为Android操作系统进行开发,我们需要一个模拟器来测试我们的应用程序的运行。Android Studio是用于构建、测试和发布Android应用程序的官方IDE/SDK。
,前往官方网站下载并在您的机器上安装Android Studio。

要使用Android Studio来开发Flutter项目,你需要安装以下插件。

要搭建一个Flutter项目的脚手架,运行以下命令。

flutter create shared_pref

该命令创建了一个文件夹,shared_pref ,并在其中放置一个Flutter项目。你可以使用VS Code或Android Studio打开该项目。

安装shared_preferences

现在我们已经准备好Flutter SDK,是时候安装shared_preferences 插件了。

打开pubspec.yaml 文件,在dependencies 部分添加shared_preferences

dependencies:
  flutter:
    sdk: flutter
  shared_preferences:

这将安装最新版本的依赖关系。

为了使用shared_preferences 插件,我们必须将其导入我们的文件中。

import 'package:shared_preferences/shared_preferences.dart';

shared_preferences 插件导出了一个SharedPreferences 类,它有一些方法可以用来设置 SharedPreferences 中各种原始类型的数据。它有一个方法,getInstance ,用来创建一个SharedPreferences 的实例。

SharedPreferences prefs = await SharedPreferences.getInstance();

getInstance 创建并返回一个SharedPreferences 实例。prefs 持有SharedPreferences 的实例。

shared_preferences 方法

在本节中,我们将演示如何向SharedPreferences添加数据以及从SharedPreferences中获取、编辑和删除数据。

添加数据

可以向SharedPreferences添加原始类型的数据。我们可以添加以下原始类型。

  • int
  • string
  • bool
  • double

每个原始类型都有其相应的setter方法。(注意:键值对的关键是字符串)。

添加int

prefs.setInt('counter', 1);

这将在SharedPreferences的counter 表中添加一个int,1

添加字符串

prefs.setString('counter', "yes");

这将添加一个字符串,"yes" ,到counter

添加bool

prefs.setBool('counter', true);

这将添加一个bool,true, 到counter

添加双数

prefs.setDouble('counter', 10.2);

将一个双倍值,10.2 ,添加到counter

检索数据

现在,让我们看看如何从SharedPreferences中检索数据。由于我们有用于原始类型的setter方法,所以我们有用于检索数据的getter方法。

获取int数据

int value = prefs.getInt('counter');

getInt 方法用于从SharedPreferences中检索一个int value

value // 1

Get bool data

bool value = prefs.getBool('counter');

这个方法getBool ,从SharedPreferences中返回一个布尔值。

value // true

获取双倍数据

double value = prefs.getDouble('counter');

getDouble 方法从SharedPreferences中返回一个双数值。

value // 10.2

获取字符串数据

string value = prefs.getString('counter');

getString 方法从SharedPreferences中返回一个字符串值。

value // "yes"

null 价值

如果数据不存在于SharedPreferences中,将返回一个null 值。

prefs.getInt("_counter")
// null

prefs.getBool("_counter")
// null

prefs.getString("_counter")
// null

prefs.getDouble("_counter")
// null

删除数据

要从SharedPreferences中删除数据,我们将使用remove 方法。数据的键被传递给.remove 方法,因此SharedPreferences 中的键值对数据被删除。

prefs.remove("counter");

这里,SharedPreferences 中的counter 被删除。

验证数据是否存在

我们可以在读或写之前,在SharedPreferences 中检查一下数据是否存在。要做到这一点,我们将使用containsKey 方法。

containsKey 方法在其参数中接受数据的键,并使用它来检查SharedPreferences中的键是否存在。

该方法返回一个bool,truefalse

prefs.containsKey("counter")
// true

在上面的例子中,counter 存在于SharedPreferences中。这就是为什么它返回true

prefs.containsKey("_counter")
// false

_counter 不存在,所以它返回false

在Flutter中使用shared_preferences

默认情况下,Flutter会在你搭建新项目的时候添加一个计数器项目。这个计数器项目使我们能够在按下FloatingActionButton 时递增一个计数器。计数器的当前状态会在它被增加时显示出来。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

当应用程序被销毁或关闭时,counter 会恢复为0 。我们将使用SharedPreferences来保持计数器的状态,以便计数器的值从应用程序关闭前的位置开始。

让我们开始行动吧。

首先,导入shared_preferences 插件。

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

接下来,在MyHomePageState widget中添加一个initState lifecycle方法。当一个有状态的widget被初始化时,这个lifecycle方法被调用。

在这里,我们将从SharedPreferences加载计数器。如果存在,我们将把它作为计数器的值。如果没有,我们就把0 赋给这个计数器。

  void loadCounter() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _counter = (prefs.getInt('counter') ?? 0);
    });
  }

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

现在让我们把_incrementCounter 函数变成async 函数。在这个函数中,我们将从SharedPreferences中获取计数器,使其增量,然后用增量来设置计数器,同时在SharedPreferences中设置增量。

  void _incrementCounter() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _counter = ((prefs.getInt('counter') ?? 0) + 1);
      prefs.setInt('counter', _counter);
    });
  }

现在我们的Flutter应用程序可以在关闭和重启时记住计数器的最后值。

测试我们的Flutter应用程序

首先,让我们启动我们的应用程序。

Flutter SharedPreferences Demo: Start App

递增到7。

Flutter SharedPreferences Demo: Increment to 3 Flutter SharedPreferences Demo: Increment to 7

现在,让我们试着杀死该应用程序。

Flutter SharedPreferences Demo: Killing the App

重启应用程序后,按钮的数量应该仍然显示为7。

Flutter SharedPreferences Demo: Restart App Flutter SharedPreferences Demo: Increment to 7

使用SharedPreferences实现闪屏

我们可以使用SharedPreferences在Flutter中实现一个闪屏。

闪屏会在应用程序首次启动时出现,并且在随后启动该应用程序时不再出现。

假设我们有一个应用程序有两个屏幕:ProfileScreenSplashScreen 。我们将钩住MyApp 小组件中的initState 方法。从那里,我们将一直检查共享偏好中的数据--比方说newLaunch 。如果这个newLaunchtrue ,就会显示SplashScreen ,一段时间后,就会显示ProfileScreenSplashScreen 将重置newLaunchfalse

如果newLaunchfalse ,则跳过SplashScreen ,显示ProfileScreen

让我们来编写我们的闪屏和简介屏幕的代码!

lib 文件夹内创建一个文件夹,screens

mkdir lib/screens
touch lib/screens/ProfileScreen.dart lib/screens/SplashScreen.dart

让我们编辑MyApp widget,如下所示。

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'screens/ProfileScreen.dart';
import 'screens/SplashScreen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'SharedPreferences Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: LoadPage() //MyHomePage(title: 'SharedPreferences Demo'),
        );
  }
}

class LoadPage extends StatefulWidget {
  LoadPage({Key key}) : super(key: key);

  @override
  LoadPageState createState() => LoadPageState();
}

class LoadPageState extends State {
  var newLaunch;

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

  loadNewLaunch() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      bool _newLaunch = ((prefs.getBool('newLaunch') ?? true));
      newLaunch = _newLaunch;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(body: newLaunch ? SplashScreen() : ProfileScreen());
  }
}

我们有LoadPage widget和它的状态widget,LoadPageState 。在LoadPageState ,我们有一个方法,loadNewLaunch ,它检查从SharedPrefs获得newLaunch 数据,并将其分配给newLaunch 状态变量。

LoadPageStatebuild 方法中,小部件检查newLaunch 状态。如果状态是true ,这意味着应用程序是第一次启动,SplashScreen widget被显示。如果不是true ,就会显示ProfileScreen

让我们对SplashScreen widget进行编码。

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

class SplashScreen extends StatefulWidget {
  SplashScreen({Key key}) : super(key: key);

  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  resetNewLaunch() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    if (prefs.containsKey("newLaunch")) {
      prefs.setBool('newLaunch', false);
    } else {
      prefs.setBool('newLaunch', false);
    }
  }

  @override
  void initState() {
    super.initState();
    Timer(
        Duration(seconds: 3),
        () => Navigator.pushReplacement(context,
                MaterialPageRoute(builder: (context) {
              resetNewLaunch();
              return ProfileScreen();
            })));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
            color: Colors.blue,
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('Splash Screen',
                      style: new TextStyle(color: Colors.white, fontSize: 40)),
                ],
              ),
        )
      )
    );
  }
}

resetNewLaunch 方法将SharedPrefs中的newLaunch 数据设置为false

initState 方法中,SplashScreen 调用resetNewLaunch 方法,将SharedPrefs中的newLaunch 数据设置为false 。这将导致应用程序只在随后启动时显示ProfileScreen

定时器代码在显示ProfileScreen 之前等待了三秒钟。

现在让我们对ProfileScreen 进行编码。

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

class ProfileScreen extends StatefulWidget {
  ProfileScreen({Key key}) : super(key: key);

  @override
  _ProfileScreenState createState() => _ProfileScreenState();
}

class _ProfileScreenState extends State<ProfileScreen> {
  clearSharedPrefs() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.remove('newLaunch');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Profile"),
        ),
        body: Container(
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('Profile Screen', style: new TextStyle(fontSize: 40)),
                RaisedButton(
                  child: Text("Clear SharedPrefs"),
                  onPressed: clearSharedPrefs,
                )
              ],
            ),
          ),
        ));
  }
}

这里没有什么好说的。我们有一个Clear SharedPrefs按钮,可以清除SharedPrefs中的newLaunch 数据。这个动作将使应用程序在下次启动时显示SplashScreen

测试我们的闪屏

安装后第一次启动时,闪屏和简介屏幕应该如下。

Flutter SharedPreferences Demo: Splash Screen on App Launch Flutter SharedPreferences Demo: Profile Screen at Launch

SplashScreen 首先显示,其次是ProfileScreen

随后的启动应该显示以下屏幕。

Flutter SharedPreferences Demo: Profile Screen Upon Subsequent Launch Flutter SharedPreferences Demo: Profile Screen Upon Subsequent Launch Flutter SharedPreferences Demo: Profile Screen Upon Subsequent Launch

SplashScreen 不会再出现,而ProfileScreen 会直接出现。

总结

在本教程中,我们介绍了什么是SharedPreferences以及它是如何在Android和iOS应用程序中使用的。我们还介绍了shared_preferences 插件,并学习了如何用SharedPreferences设置Flutter。

接下来,我们学习了如何导入shared_preferences 插件,了解了如何初始化它的实例,并回顾了它的方法和所有这些方法的作用。我们修改了一个普通的Flutter计数器项目,以展示如何使用shared_preferences 插件来持久化计数器的值,并在应用程序被杀死和重新启动后将其检索出来。

本教程中所有例子的源代码都可以在GitHub上找到。

The postUsing SharedPreferences in Flutter to store data locallyappeared first onLogRocket Blog.