Flutter实时数据共享插件streaming_shared_preferences的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter实时数据共享插件streaming_shared_preferences的使用

简介

streaming_shared_preferences 是一个为Flutter项目提供反应式键值存储的库。它在 shared_preferences 的基础上增加了对值变化的监听功能,使保持小部件与持久化值同步变得非常容易。

  • pub package
  • Build Status
  • Coverage Status

开始使用

添加依赖

首先,在你的 pubspec.yaml 文件中添加 streaming_shared_preferences 依赖:

dependencies:
  streaming_shared_preferences: ^2.0.0

如果你已经在使用 shared_preferences,请将其替换为 streaming_shared_preferences

获取实例

通过异步调用 instance 来获取 StreamingSharedPreferences 实例:

import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';

...
WidgetsFlutterBinding.ensureInitialized();
final preferences = await StreamingSharedPreferences.instance;

注意:变更检测仅在Dart端工作。因此,如果你想响应值的变化,应始终使用 StreamingSharedPreferences(而不是 SharedPreferences)来存储值。

创建第一个流式偏好设置

以下是一个简单的例子,展示如何在每次 counter 整数值变化时打印其值到控制台:

// 获取对 counter 值的引用,并在为空时提供默认值 0。
Preference<int> counter = preferences.getInt('counter', defaultValue: 0);

// "counter" 是 Preference<int> 类型 - 它可以做任何 Stream<int> 可以做的事情。
// 我们只是监听它并打印值到控制台。
counter.listen((value) {
  print(value);
});

// 在代码其他地方更新值。
counter.setValue(1);

// 这和上面是一样的,但上面更方便。
preferences.setInt('counter', 2);

假设没有先前存储的值(即为null),上述示例将依次打印 012 到控制台。

将值连接到Flutter小部件

虽然它可以与 StreamBuilder 一起完美工作,但推荐的方式是使用 PreferenceBuilder 小部件。如果只有少量需要存储的值,可以直接内联监听:

class MyCounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return PreferenceBuilder<int>(
      preference: preferences.getInt('counter', defaultValue: 0),
      builder: (BuildContext context, int counter) {
        return Text('Button pressed $counter times!');
      }
    );
  }
}

当有多个偏好设置时,建议创建一个类来集中管理这些 Preference 对象:

class MyAppSettings {
  MyAppSettings(StreamingSharedPreferences preferences)
      : counter = preferences.getInt('counter', defaultValue: 0),
        nickname = preferences.getString('nickname', defaultValue: '');

  final Preference<int> counter;
  final Preference<String> nickname;
}

在应用入口点处,初始化 StreamingSharedPreferences 并传递给 MyAppSettings,然后将其传递给需要使用的组件:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final preferences = await StreamingSharedPreferences.instance;
  final settings = MyAppSettings(preferences);
  
  runApp(MyApp(settings));
}

class MyCounterWidget extends StatelessWidget {
  MyCounterWidget(this.settings);
  final MyAppSettings settings;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        PreferenceBuilder<String>(
          preference: settings.nickname,
          builder: (context, nickname) => Text('Hey $nickname!'),
        ),
        PreferenceBuilder<int>(
          preference: settings.counter,
          builder: (context, counter) => Text('You have pushed the button $counter times!'),
        ),
        FloatingActionButton(
          onPressed: () {
            final currentCounter = settings.counter.getValue();
            settings.counter.setValue(currentCounter + 1);
          },
          child: Icon(Icons.add),
        ),
      ],
    );
  }
}

完整的工作示例可以在此链接查看。

存储自定义类型

整个库设计支持轻松存储自定义数据类型,每个内置类型都有自己的 PreferenceAdapter。对于大多数情况,提供了处理常见问题的便利适配器 JsonAdapter,它帮助你以JSON格式存储和检索值。

例如,如果你有一个名为 SampleObject 的类:

class SampleObject {
  SampleObject(this.isAwesome);
  final bool isAwesome;

  SampleObject.fromJson(Map<String, dynamic> json) :
    isAwesome = json['isAwesome'];

  Map<String, dynamic> toJson() => { 'isAwesome': isAwesome };
}

你可以这样使用 JsonAdapter

final sampleObject = preferences.getCustomValue<SampleObject>(
  'my-key',
  defaultValue: SampleObject.empty(),
  adapter: JsonAdapter(
    deserializer: (value) => SampleObject.fromJson(value),
  ),
);

对于使用 built_value 的模型,可以这样做:

final sampleObject = preferences.getCustomValue<SampleObject>(
  'my-key',
  defaultValue: SampleObject.empty(),
  adapter: JsonAdapter(
    serializer: (value) => serializers.serialize(value),
    deserializer: (value) => serializers.deserialize(value),
  ),
);

总结

streaming_shared_preferences 提供了一种简单且强大的方式来处理Flutter中的持久化状态管理。它不仅简化了代码逻辑,还使得UI能够自动响应数据的变化。希望这个指南能帮助你更好地理解和使用该库!


更多关于Flutter实时数据共享插件streaming_shared_preferences的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter实时数据共享插件streaming_shared_preferences的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用streaming_shared_preferences插件来实现实时数据共享的示例代码。streaming_shared_preferences是一个扩展自shared_preferences的插件,它提供了监听SharedPreferences数据变化的能力。

步骤 1: 添加依赖

首先,你需要在pubspec.yaml文件中添加streaming_shared_preferences依赖:

dependencies:
  flutter:
    sdk: flutter
  streaming_shared_preferences: ^2.0.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

步骤 2: 导入包

在你的Dart文件中导入streaming_shared_preferences包:

import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';

步骤 3: 使用插件

下面是一个简单的示例,展示了如何使用streaming_shared_preferences来存储和监听SharedPreferences中的数据变化。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Streaming SharedPreferences Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SharedPreferencesDemo(),
    );
  }
}

class SharedPreferencesDemo extends StatefulWidget {
  @override
  _SharedPreferencesDemoState createState() => _SharedPreferencesDemoState();
}

class _SharedPreferencesDemoState extends State<SharedPreferencesDemo> {
  late StreamingSharedPreferences _streamingSharedPreferences;
  late SharedPreferences _sharedPreferences;
  String? _value;

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

  Future<void> _initSharedPreferences() async {
    _streamingSharedPreferences = await StreamingSharedPreferences.getInstance();
    _sharedPreferences = _streamingSharedPreferences.sharedPreferences;

    // 监听SharedPreferences中的某个key的变化
    _streamingSharedPreferences.listenForKey('my_key').listen((value) {
      if (mounted) {
        setState(() {
          _value = value;
        });
      }
    }, onError: (error) {
      print('Error listening to SharedPreferences: $error');
    });

    // 初始化时读取一次值
    _value = _streamingSharedPreferences.getString('my_key');
  }

  void _updateValue(String newValue) async {
    await _sharedPreferences.setString('my_key', newValue);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Streaming SharedPreferences Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Current Value:',
              style: TextStyle(fontSize: 20),
            ),
            Text(
              _value ?? 'null',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 20),
            TextField(
              decoration: InputDecoration(labelText: 'Enter new value'),
              onSubmitted: (newValue) {
                _updateValue(newValue);
              },
            ),
          ],
        ),
      ),
    );
  }
}

解释

  1. 依赖导入:我们在pubspec.yaml中添加streaming_shared_preferences依赖,并导入到Dart文件中。
  2. 初始化:在initState方法中,我们初始化StreamingSharedPreferences实例,并监听my_key的变化。当my_key的值发生变化时,我们更新UI。
  3. 读取和更新值:我们在初始化时读取一次my_key的值,并提供一个TextField让用户可以更新这个值。更新值时会调用_updateValue方法,该方法使用SharedPreferencessetString方法来更新值。

这样,你就可以在Flutter应用中使用streaming_shared_preferences来实现实时数据共享和监听。

回到顶部