Flutter状态持久化插件hydrated_bloc_integration的使用

Flutter状态持久化插件hydrated_bloc_integration的使用

在Flutter应用开发中,状态管理是一个重要的环节。hydrated_bloc_integration 插件通过结合 hydrated_blocflutter_bloc 来实现状态的持久化。该插件允许你将状态保存到本地存储(如文件系统或内存)中,并在应用重启时恢复状态。

示例代码

以下是一个完整的示例,展示了如何使用 hydrated_bloc_integration 插件来实现状态的持久化。

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hydrated_bloc_integration/hydrated_bloc_integration.dart';
import 'package:path_provider/path_provider.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 关闭hydrated功能。
  HydratedBlocConfig.offMode = true;

  HydratedBloc.storage = await HydratedStorage.build(
    storageDirectory: kIsWeb
        ? HydratedStorage.webStorageDirectory
        : await getTemporaryDirectory(),
  );
  runApp(App());
}

class App extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => BrightnessCubit(),
      child: AppView(),
    );
  }
}

class AppView extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return BlocBuilder<BrightnessCubit, Brightness>(
      builder: (context, brightness) {
        return MaterialApp(
          theme: ThemeData(brightness: brightness),
          home: CounterPage(),
        );
      },
    );
  }
}

class CounterPage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return BlocProvider<CounterBloc>(
      create: (_) => CounterBloc(),
      child: CounterView(),
    );
  }
}

class CounterView extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final textTheme = Theme.of(context).textTheme;
    return Scaffold(
      appBar: AppBar(title: const Text('Counter')),
      body: Center(
        child: BlocBuilder<CounterBloc, int>(
          builder: (context, state) {
            return Text('$state', style: textTheme.displayMedium);
          },
        ),
      ),
      floatingActionButton: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            child: const Icon(Icons.brightness_6),
            onPressed: () => context.read<BrightnessCubit>().toggleBrightness(),
          ),
          const SizedBox(height: 4),
          FloatingActionButton(
            child: const Icon(Icons.add),
            onPressed: () {
              context.read<CounterBloc>().add(CounterIncrementPressed());
            },
          ),
          const SizedBox(height: 4),
          FloatingActionButton(
            child: const Icon(Icons.remove),
            onPressed: () {
              context.read<CounterBloc>().add(CounterDecrementPressed());
            },
          ),
          const SizedBox(height: 4),
          FloatingActionButton(
            child: const Icon(Icons.delete_forever),
            onPressed: () => HydratedBloc.storage.clear(),
          ),
        ],
      ),
    );
  }
}

abstract class CounterEvent {}

class CounterIncrementPressed extends CounterEvent {}

class CounterDecrementPressed extends CounterEvent {}

class CounterBloc extends HydratedBloc<CounterEvent, int> {
  CounterBloc() : super(0) {
    on<CounterIncrementPressed>((event, emit) => emit(state + 1));
    on<CounterDecrementPressed>((event, emit) => emit(state - 1));
  }

  [@override](/user/override)
  int fromJson(Map<String, dynamic> json) => json['value'] as int;

  [@override](/user/override)
  Map<String, int> toJson(int state) => {'value': state};
}

class BrightnessCubit extends HydratedCubit<Brightness> {
  BrightnessCubit() : super(Brightness.light);

  void toggleBrightness() {
    emit(state == Brightness.light ? Brightness.dark : Brightness.light);
  }

  [@override](/user/override)
  Brightness fromJson(Map<String, dynamic> json) {
    return Brightness.values[json['brightness'] as int];
  }

  [@override](/user/override)
  Map<String, dynamic> toJson(Brightness state) {
    return {'brightness': state.index};
  }
}

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

1 回复

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


当然,hydrated_bloc_integration 是一个用于在 Flutter 应用中持久化 Bloc 状态的插件。它结合了 hydrated_blocflutter_bloc,使得状态管理更加高效和持久化。以下是一个简单的示例,展示如何在 Flutter 项目中使用 hydrated_bloc_integration 插件。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  flutter_bloc: ^8.0.0
  hydrated_bloc: ^8.0.0
  hydrated_bloc_integration: ^2.0.0  # 确保版本与你的Flutter环境兼容
  # 其他依赖...

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

2. 配置 HydratedBloc

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

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:hydrated_bloc_integration/hydrated_bloc_integration.dart';
import 'package:your_app/your_bloc.dart';  // 导入你的Bloc文件

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final hydratedStorage = await HydratedStorage.build(
    storageDirectory: await getApplicationDocumentsDirectory(),
  );

  runApp(
    BlocProvider.value(
      value: HydratedBlocOverrides.value(
        hydratedBlocs: [YourBloc.instance],  // 添加你的Bloc实例
        storage: hydratedStorage,
      ),
      child: MaterialApp(
        home: YourHomePage(),
      ),
    ),
  );
}

3. 创建一个简单的 Bloc

接下来,创建一个简单的 Bloc 来管理应用的状态。假设我们有一个计数器 Bloc:

import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
import 'dart:math' as math;

part 'counter_event.dart';
part 'counter_state.dart';

class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterInitial()) {
    on<CounterIncremented>(_increment);
    on<CounterReset>(_reset);
  }

  void _increment(CounterIncremented event, Emitter<CounterState> emit) {
    emit(CounterState(count: state.count + 1));
  }

  void _reset(CounterReset event, Emitter<CounterState> emit) {
    emit(CounterState(count: 0));
  }
}

counter_event.dart:

part of 'counter_bloc.dart';

abstract class CounterEvent {}

class CounterIncremented extends CounterEvent {}

class CounterReset extends CounterEvent {}

counter_state.dart:

part of 'counter_bloc.dart';

class CounterState {
  final int count;

  CounterState(this.count);

  @override
  String toString() => 'CounterState(count: $count)';
}

class CounterInitial extends CounterState {
  CounterInitial() : super(0);
}

4. 使用 Bloc 和 HydratedBloc

在你的组件中使用 BlocBuilder 来监听状态变化:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:your_app/counter_bloc.dart';  // 导入你的Bloc文件

class YourHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Hydrated Bloc Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('${context.select((CounterState state) => state.count)}'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => context.read<CounterBloc>().add(CounterIncremented()),
              child: Text('Increment'),
            ),
            ElevatedButton(
              onPressed: () => context.read<CounterBloc>().add(CounterReset()),
              child: Text('Reset'),
            ),
          ],
        ),
      ),
    );
  }
}

5. 初始化 HydratedBloc 实例

确保在你的 Bloc 文件中有一个单例实例,这样 HydratedBloc 可以正确管理它:

// counter_bloc.dart

class CounterBloc extends Bloc<CounterEvent, CounterState> {
  // 单例实例
  static final CounterBloc instance = CounterBloc();

  CounterBloc() : super(CounterInitial()) {
    on<CounterIncremented>(_increment);
    on<CounterReset>(_reset);
  }

  // ... 其他代码 ...
}

通过以上步骤,你已经成功地在 Flutter 应用中配置了 hydrated_bloc_integration 插件,并实现了状态持久化。每次应用重新启动时,Bloc 的状态将从持久化存储中恢复。

回到顶部