Flutter持久化存储插件hydrated的使用

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

Flutter持久化存储插件hydrated的使用

Hydrated 是一个用于Flutter应用中的持久化存储插件,它能够自动将数据保存到本地存储并在创建时自动恢复。以下是如何使用Hydrated进行数据持久化的完整示例。

易于使用

所有的值都通过 shared_preferences 进行持久化,并在创建时自动恢复。

// 创建一个 HydratedSubject 实例来保存和恢复整数类型的计数值
final count$ = HydratedSubject<int>("count", seedValue: 0);

/// 下次创建时,count$ 将自动用42进行水合(即恢复)
count$.add(42);

BLoC准备就绪

Hydrated 可以很容易地集成到 BLoC 模式中:

class HydratedBloc {
  final _count$ = HydratedSubject<int>("count", seedValue: 0);

  // 获取流观察者
  ValueObservable<int> get count$ => _count$.stream;
  
  // 获取 Sink 以便设置计数值
  Sink<int> get setCount => _count$.sink;

  dispose() {
    _count$.close();
  }
}

支持简单类型和序列化类

支持所有 shared_preferences 类型,如 int, double, bool, String, List<String> 等。

final count$ = HydratedSubject<int>("count");

对于序列化类,可以通过 hydratepersist 参数实现:

final user$ = HydratedSubject<User>(
  "user",
  hydrate: (String s) => User.fromJson(s),
  persist: (User user) => user.toJson(),
);

可靠性和扩展性

Hydrated 经过全面测试,支持任何键值对数据存储方案,只需实现 KeyValueStore 接口即可。

class MyAwesomeKeyValueStore implements KeyValueStore {
  /// 你的实现代码...
}

final user = HydratedSubject<User>(
  "user",
  hydrate: (String s) => User.fromJson(s),
  persist: (User user) => user.toJson(),
  keyValueStore: MyAwesomeKeyValueStore()
);

示例演示

以下是 Hydrated 在应用重启之间的工作效果演示图:

Hydrated BehaviorSubject between app restarts

完整示例代码

下面是一个完整的 Flutter 应用示例,展示了如何使用 Hydrated 来持久化计数器的状态:

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hydrated Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Hydrated Demo'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String _title;
  final _count = HydratedSubject<int>("count", seedValue: 0); // 初始化 HydratedSubject

  MyHomePage({
    Key? key,
    required String title,
  })  : _title = title,
        super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(this._title),
      ),
      body: Center(
        child: StreamBuilder<int>( // 使用 StreamBuilder 监听 _count 的变化
          stream: _count,
          initialData: _count.value, // 初始数据为当前计数值
          builder: (context, snap) => Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('You have pushed the button this many times:'),
              Text(
                '${snap.data}', // 显示当前计数值
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter, // 点击按钮增加计数
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

  void _incrementCounter() {
    _count.value++; // 增加计数值
  }

  void dispose() {
    _count.close(); // 关闭 HydratedSubject
  }
}

更多关于Flutter持久化存储插件hydrated的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter持久化存储插件hydrated的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用hydrated插件进行持久化存储的代码示例。hydrated插件通常与hydrated_bloc一起使用,以便轻松地在BLoC(Business Logic Component)架构中实现状态持久化。不过,为了简单起见,这里仅展示如何使用hydrated插件进行基本的持久化存储。

首先,确保你已经在pubspec.yaml文件中添加了必要的依赖:

dependencies:
  flutter:
    sdk: flutter
  hydrated: ^3.0.0  # 请检查最新版本号
  # 如果你使用BLoC架构,可以添加以下依赖
  # flutter_bloc: ^x.x.x
  # hydrated_bloc: ^x.x.x

然后,运行flutter pub get来获取这些依赖。

接下来,让我们编写一些代码来展示如何使用hydrated插件进行持久化存储。

1. 配置Hydrated Storage

在应用的入口文件(通常是main.dart)中,配置HydratedStorage

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
  HydratedStorage storage = HydratedStorage.build(
    storageDirectory: (await getApplicationDocumentsDirectory()).path,
    backingStore: sharedPreferences,
  );

  runApp(HydratedApp(
    storage: storage,
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

2. 创建持久化数据模型

创建一个简单的数据模型,并确保它实现了Hydratable接口:

import 'package:hydrated/hydrated.dart';

class UserData implements Hydratable<UserData> {
  String name;
  int age;

  UserData({required this.name, required this.age});

  UserData.fromJson(Map<String, dynamic> json)
      : name = json['name'] as String,
        age = json['age'] as int;

  @override
  Map<String, dynamic> toJson() {
    return {'name': name, 'age': age};
  }

  @override
  UserData fromHydrationData(Map<String, dynamic> data) {
    return UserData.fromJson(data);
  }
}

3. 使用HydratedBox进行持久化存储

在需要使用持久化存储的Widget中,使用HydratedBox

import 'package:flutter/material.dart';
import 'package:hydrated/hydrated.dart';
import 'user_data.dart'; // 假设你的UserData类在这个文件中

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late HydratedBoxController<UserData> _boxController;

  @override
  void initState() {
    super.initState();
    _boxController = HydratedBoxController<UserData>(
      storageKey: 'userData',
      defaultValue: UserData(name: 'John Doe', age: 30),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Hydrated Storage Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            Text('Name: ${_boxController.value.name}'),
            Text('Age: ${_boxController.value.age}'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  _boxController.value = UserData(
                    name: 'Jane Doe',
                    age: 28,
                  );
                });
              },
              child: Text('Update User Data'),
            ),
          ],
        ),
      ),
    );
  }

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

在这个例子中,我们创建了一个UserData类来实现Hydratable接口,并在HomeScreen中使用HydratedBoxController来管理持久化存储。当用户点击按钮更新用户数据时,新的数据将被持久化存储。

请注意,这只是一个简单的示例。在实际应用中,你可能需要根据具体需求调整存储逻辑和数据模型。如果你使用BLoC架构,可以结合hydrated_bloc库来实现更复杂的持久化逻辑。

回到顶部