Flutter插件bloobit的使用_Bloobit 是一种状态管理方法,灵感来源于 BloC 模式

发布于 1周前 作者 yuanlaile 最后一次编辑是 5天前 来自 Flutter

Flutter插件bloobit的使用_Bloobit 是一种状态管理方法,灵感来源于 BloC 模式

Bloobit 是一种状态管理方法,灵感来源于 BloC 模式,但默认情况下不使用流(或观察者模式)。Bloobit 和 BloC 模式都旨在将展示逻辑与业务逻辑分离,但 Bloobit 并不是 BloC 模式的实现。当你需要改变状态时,只需调用 setState() 即可。没有魔法,只有大约 100 行代码,具体取决于如何计算。你可以阅读并理解这些代码。

如果你需要遵循 BloC 模式,我推荐使用 CubitBloc 库 中。

Bloobit 目前处于测试阶段,但正在接近全面发布。

实现业务逻辑

通过扩展 <code>Bloobit<TState> 类,并通过方法发送消息或事件到 <code>Bloobit。当状态变化时,调用 <code>setState()

/// 这个类扩展了 `Bloobit` 并通过方法实现了业务逻辑。
/// 当状态变化时,我们调用 `setState()`
class AppBloobit extends Bloobit<AppState> {
  int get callCount => state.callCount;
  bool get isProcessing => state.isProcessing;
  bool get displayWidgets => state.displayWidgets;

  final CountServerService countServerService;

  AppBloobit(this.countServerService, {void Function(AppState)? onSetState})
      : super(const AppState(0, false, true), onSetState: onSetState);

  void hideWidgets() {
    setState(state.copyWith(displayWidgets: false));
  }

  Future<void> callGetCount() async {
    setState(state.copyWith(isProcessing: true));

    final callCount = await countServerService.getCallCount();

    setState(state.copyWith(isProcessing: false, callCount: callCount));
  }
}

状态

我们通常使用不可变状态,但也可以使用可变状态。Bloobit 对此没有偏好。Bloobit 只是 setState() 的一个包装器。

/// 应用程序的不可变状态
@immutable
class AppState {
  final int callCount;
  final bool isProcessing;
  final bool displayWidgets;

  const AppState(
    this.callCount,
    this.isProcessing,
    this.displayWidgets,
  );

  AppState copyWith({
    int? callCount,
    bool? isProcessing,
    bool? displayWidgets,
  }) =>
      AppState(
        callCount ?? this.callCount,
        isProcessing ?? this.isProcessing,
        displayWidgets ?? this.displayWidgets,
      );
}

你可以轻松地在 widget 树中检查状态和 Bloobit 使用开发工具。查看下一节关于 <code>BloobitPropagator 的内容。

开发工具

BloobitWidget

这是使用 Bloobit 的最简单方式。将 <code>BloobitWidget> 放入树中,并像这样实例化你的 <code>Bloobit>。查看第二个示例以了解如何使用依赖注入和 <a href="https://pub.dev/packages/ioc_container">ioc_container</a> 使用 Bloobit。

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) => MaterialApp(
        title: 'Bloobit Sample',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: BloobitWidget<AppBloobit>(
          bloobit: AppBloobit(),
          builder: (context, bloobit) => MyHomePage(
            title: 'Bloobit Sample',
            bloobit: bloobit,
          ),
        ),
      );
}

在 widget 树中暴露 Bloobit

如果你想嵌套 widget,你需要将 widget 包裹在 <code>BloobitPropagator> 中。这是一个 <a href="https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html">InheritedWidget</a>BloobitPropagator 将把 Bloobit 传递给子节点。

class MyApp extends StatelessWidget {
  final IocContainer container;

  const MyApp(this.container, {super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: BloobitPropagator<AppBloobit>(
        bloobit: container.get<AppBloobit>(),
        child: const Home(),
      ),
    );
  }
}

访问 Bloobit

你可以在 <code>BloobitPropagator> 下的任何 widget 中访问 <code>Bloobit>。使用 <a href="https://pub.dev/documentation/bloobit/latest/bloobit/BloobitPropagator/of.html"><code>BloobitPropagator.of</code></a>

class CounterDisplay extends StatelessWidget {
  const CounterDisplay({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final bloobit = BloobitPropagator.of<AppBloobit>(context).bloobit;
    return Padding(
      padding: const EdgeInsets.all(10),
      child: Container(
        height: 200,
        width: 200,
        color: const Color(0xFFEEEEEE),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            if (bloobit.isProcessing)
              const CircularProgressIndicator()
            else
              Text(
                '${bloobit.callCount}',
                style: Theme.of(context).textTheme.headline4,
              ),
          ],
        ),
      ),
    );
  }
}

转换为流

Bloobit 设计用于仅与一个 <code>StatefulWidget> 一起工作。正如你在示例中看到的,你不需要多个 <code>StatefulWidget> 来驱动多个子 widget。Bloc 旨在处理许多情况,但大多数时候并不需要使用多个 <code>StatefulWidget>。然而,你可以从 <code>Bloobit> 流式传输状态更改,并使用 <a href="https://pub.dev/packages/ioc_container">ioc_container</a> 包来连接多个监听器。查看示例文件夹中的流式传输代码。你可以使用 [StreamBuilder](https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html) 或其他多个 <code>StatefulWidget>

void main() {
  // 注册服务和视图模型到 IoC 容器
  final builder = IocContainerBuilder()
    // 一个简单的单例服务来模拟服务器计数调用
    ..addSingletonService(CountServerService())
    // 添加一个 AppState 更改的流
    ..addStream<AppState>()
    // Bloobit
    ..addSingleton((con) => AppBloobit(con.get<CountServerService>(),
        onSetState: (s) =>
            // 将状态更改流式传输到 AppState 流
            con.get<StreamController<AppState>>().add(s)));

  var container = builder.toContainer();

  container
      .get<Stream<AppState>>()
      // 将状态更改流式传输到调试控制台
      .listen((appState) => debugPrint(appState.callCount.toString()));

  runApp(MyApp(container));
}

更多关于Flutter插件bloobit的使用_Bloobit 是一种状态管理方法,灵感来源于 BloC 模式的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter插件bloobit的使用_Bloobit 是一种状态管理方法,灵感来源于 BloC 模式的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,作为一个IT专家,我可以为你提供一些关于如何在Flutter项目中集成和使用一个假想的未知功能插件 bloobit 的示例代码。请注意,由于 bloobit 是一个虚构的插件,以下代码示例是基于假设其功能类似于某种数据处理或通信插件。

首先,你需要确保 bloobit 插件已经在你的 pubspec.yaml 文件中被添加为依赖项。由于这是一个虚构的插件,假设它的依赖项声明如下:

dependencies:
  flutter:
    sdk: flutter
  bloobit: ^0.1.0  # 假设的版本号

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

接下来,在你的 Flutter 项目中,你可以通过以下方式使用 bloobit 插件:

1. 导入插件

在你的 Dart 文件中导入 bloobit 插件:

import 'package:bloobit/bloobit.dart';

2. 初始化插件

通常,插件需要在某处进行初始化。假设 bloobit 有一个初始化方法 initialize

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Bloobit.initialize();  // 假设的初始化方法
  runApp(MyApp());
}

3. 使用插件的功能

假设 bloobit 插件有一个用于数据处理的功能,比如 processData,它接收一些输入并返回处理后的结果。

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Bloobit.initialize();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Bloobit Demo'),
        ),
        body: Center(
          child: BloobitDemo(),
        ),
      ),
    );
  }
}

class BloobitDemo extends StatefulWidget {
  @override
  _BloobitDemoState createState() => _BloobitDemoState();
}

class _BloobitDemoState extends State<BloobitDemo> {
  String result = "";

  void _processData() async {
    String input = "some data to process";
    try {
      String output = await Bloobit.processData(input);  // 假设的插件方法
      setState(() {
        result = output;
      });
    } catch (e) {
      setState(() {
        result = "Error: ${e.message}";
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text("Processed Data: $result"),
        ElevatedButton(
          onPressed: _processData,
          child: Text("Process Data"),
        ),
      ],
    );
  }
}

4. 处理错误和状态管理

在上面的代码中,我们已经展示了如何处理异步操作以及捕获可能发生的错误。此外,通过使用 setState 方法,我们确保了 UI 在数据发生变化时能够及时更新。

注意事项

  • 由于 bloobit 是一个虚构的插件,上述代码中的所有方法(如 initializeprocessData)都是假设存在的。你需要查阅 bloobit 插件的实际文档来了解其真实的功能和API。
  • 插件的初始化通常只需要在应用启动时进行一次,因此通常放在 main 函数中。
  • 异步操作(如网络请求或数据处理)应该使用 asyncawait 关键字来处理,以确保代码的可读性和错误处理的方便性。

希望这个示例代码能够帮助你理解如何在 Flutter 项目中集成和使用一个未知的插件。如果你有具体的 bloobit 插件文档或更多关于其功能的信息,我可以提供更精确的代码示例。

回到顶部