Flutter功能未知插件fluxivity的使用

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

Flutter功能未知插件fluxivity的使用

Fluxivity是一个实验性的包,用于研究构建反应图的效果。

该包可以在pub.dev上找到,地址为:这里

为什么使用这个包

尽管有许多状态管理解决方案,但我经常寻找更简单的解决方案,这些方案遵循以下原则:

  • 全局应用状态
  • 视图模型只应包含值/数据访问器,而不是数据本身
  • 应该有可能构建一个类似图结构的应用程序状态。
  • 应该有可能在不等待值的情况下获取最新数据
  • 应该有可能跟踪数据的变化(如果需要)
  • 用函数方法处理变化

注意:2023-04-07:最近我发现了一个使用传统视图模型实现的例子。虽然我不太喜欢在视图模型中封装数据,但这种方法的价值我是认可的。我将在未来添加一个此类例子。

基本功能

有两个核心类:

  • Reactive
  • Computed

Reactive 类创建了一个反应属性,并跟踪其状态,通过流发布更新。最新的值总是可以通过静态值获取,而无需调用 awaitlisten。然而,有一个流可以被监听,如果你想要监听更新。Reactive 类还包含一个 addEffect 方法来处理作为值突变一部分的副作用。例如,在离线存储中更新数据,或同步数据到后端。

Computed 类与 Reactive 类类似,但是它的值始终依赖于它所依赖的类来获取其值。每当依赖类的值发生变化时,Computed 类的值也会更新。这可以用于需要派生值的地方。

示例使用

你也可以参考测试文件中的示例使用。当有更多时间时,我会添加更多的示例应用。

CurrentPage page = CurrentPage(location: 'test');

Reactive<String> appId = Reactive('app_123456789');
Reactive<CurrentPage> currentPage = Reactive(page);
Computed<String> location = Computed([currentPage], (List<Reactive<CurrentPage>> cpl) {
    Reactive<CurrentPage> page = cpl.first();
    return page.location;
});

currentPage.value.location; // 输出:test
location.value; // 输出:test

page = CurrentPage(location: 'newLocation');
currentPage.value = page;

currentPage.stream.listen((Snapshot<CurrentPage> snapshot) {
    snapshot.oldValue.location; // 输出:test
    snapshot.newValue.location; // 输出:newLocation
});

currentPage.value.location; // 输出:newLocation
location.value; // 输出:newLocation

ReactiveExtensions

ReactiveExtensions 是基于原生列表的扩展,允许你在Dart应用程序中轻松创建和操作反应式列表。使用这些扩展方法,你可以自动跟踪列表的变化,并且包会处理更新并在列表被操作时发出流。

使用

要创建一个反应式列表,请使用常规列表上的 reactive 获取器:

import 'package:fluxivity/fluxivity.dart';

void main() {
  final reactiveList = [1, 2, 3].reactive;

  // 可以订阅列表更改
  reactiveList.stream.listen((snapshot) {
    print('List updated: ${snapshot.newValue}');
  });

  // 使用常规列表方法操作列表
  reactiveList.value.add(4); // 输出:List updated: [1, 2, 3, 4]
}

解除包装

unwrap 方法在你需要从反应式列表中检索原始非反应式列表时非常有用。这在与不了解反应式对象的外部库或API一起工作时很有帮助。

示例:

final nonReactiveList = reactiveList.unwrap();
print(nonReactiveList); // 输出:[1, 2, 3, 4]

添加效果

类似于 Reactive 中可用的 addEffects 功能,你可以定义自定义函数(效果),这些函数会在列表被修改时自动执行。这使你能够在响应列表操作时执行额外的任务或副作用。

示例:

要使用 addEffects,首先使用常规列表上的 reactive 获取器创建一个反应式列表。然后,定义一个接受 Snapshot<List<int>> 的自定义函数。

import 'package:fluxivity/fluxivity.dart';

void main() {
  final reactiveList = [1, 2, 3].reactive;

  // 定义一个自定义效果函数
  void logUpdate(Snapshot<List<int>> snapshot) {
    print('List updated: ${snapshot.newValue}');
  }

  // 将效果添加到反应式列表
  reactiveList.addEffect(logUpdate);

  // 使用常规列表方法操作列表
  reactiveList.value.add(4); // 输出:List updated: [1, 2, 3, 4]
}

示例应用案例

此处 查看更多示例。

高级用法

以下是不属于日常使用的功能,但在某些情况下,你可能希望对Fluxivity如何运行具有更多的控制权。

中间件

中间件允许你扩展包的功能。Fluxivity 中间件应该扩展 FluxivityMiddleware 类并实现其中的方法。除了 shouldEmit 方法外,其他方法都返回 voidshouldEmit 方法返回一个布尔值,用于控制是否应该发射新值。这可以用来实现自定义逻辑来控制何时应该发射新的值。中间件适用于 ReactiveComputed 类。由于扩展方法依赖于实际的反应式类,因此它们通过扩展获得。但是,你将不得不使用 toReactive 方法传递中间件,而不是使用 .reactive 扩展方法。

示例:

import 'package:fluxivity/fluxivity.dart';

class LoggingMiddleware<T> extends FluxivityMiddleware<T> {
  [@override](/user/override)
  void beforeUpdate(T oldValue, T newValue) {
    print("Before update: $oldValue -> $newValue");
  }

  [@override](/user/override)
  void afterUpdate(T oldValue, T newValue) {
    print("After update: $oldValue -> $newValue");
  }

  [@override](/user/override)
  void onError(Object error, StackTrace stackTrace) {
    print("Error: $error\n$stackTrace");
  }

  [@override](/user/override)
  bool shouldEmit(T oldValue, T newValue) {
    return true;
  }
}

要在代码中使用中间件,你可以像这样初始化一个带有中间件的反应式对象:

Reactive<String> reactive = Reactive('test', { middlewares: [LoggingMiddleware<String>()] });

批量更新

Fluxivity 允许你以批处理模式监听更新,而不是单独监听事件。这在你想要对反应式值执行多个操作并且只想监听最终值时非常有用。这种批处理更新也可以与中间件一起使用。如果中间件阻止了流的发射,那么批处理更新也不会被发射。批处理更新可用于 ReactiveComputed 类。它也适用于所有扩展方法。你还可以嵌套批处理更新,在这种情况下,只有在外层批处理更新结束时才会发出更新。

final reactive = Reactive<int>(0);

// 开始批处理更新
reactive.startBatchUpdate();

// 执行多次更新
reactive.value = 1;
reactive.value = 2;
reactive.value = 3;
reactive.value = 4;

// 结束批处理更新,将发出最后缓冲的值
reactive.endBatchUpdate(); // 输出:4

// 开始批处理更新
reactive.startBatchUpdate();

reactive.value = 5;
reactive.value = 6;
reactive.value = 7;
reactive.value = 8;

// 结束批处理更新,将发出最后缓冲的值
reactive.endBatchUpdate(publishAll: true); // 输出:5, 6, 7, 8

与存储提供者一起使用

Fluxivity 可以与现有的存储提供者(如 Hive、Shared Preferences 等)一起使用。以下是如何使用 Fluxivity 与 Hive 的示例。假设你已经设置了 Hive 并配置了类型适配器,你可以创建一个名为 HiveReactive 的自定义类,该类扩展了 Reactive 类并实现了从 Hive 加载和保存的方法。

import 'package:fluxivity/core/reactive.dart';
import 'package:hive/hive.dart';

class HiveReactive<T> extends Reactive<T> {
  final String boxName;
  final String key;

  HiveReactive(this.boxName, this.key, T initialValue) : super(initialValue) {
    _loadFromHive();
  }

  [@override](/user/override)
  set value(T newValue) {
    super.value = newValue;
    _saveToHive();
  }

  Future<void> _loadFromHive() async {
    final box = await Hive.openBox<T>(boxName);
    if (box.containsKey(key)) {
      super.value = box.get(key);
    }
  }

  Future<void> _saveToHive() async {
    final box = await Hive.openBox<T>(boxName);
    box.put(key, value);
  }
}

更多关于Flutter功能未知插件fluxivity的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter功能未知插件fluxivity的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,作为IT专家,我可以为你提供一个关于如何在Flutter项目中使用未知插件(例如fluxivity)的示例代码框架。请注意,由于“fluxivity”并非一个广为人知的Flutter插件(在我最后的更新信息中),我将假设它是一个自定义或较少使用的插件,并且你需要按照其文档或源代码进行集成。

第一步:添加依赖

首先,你需要在pubspec.yaml文件中添加该插件的依赖。由于“fluxivity”的具体依赖信息未知,这里我使用了一个假设的依赖格式:

dependencies:
  flutter:
    sdk: flutter
  fluxivity: ^x.y.z  # 替换为实际的版本号

第二步:导入插件

在你的Dart文件中导入该插件。假设该插件提供了一个主要的类Fluxivity,你可以这样导入:

import 'package:fluxivity/fluxivity.dart';

第三步:使用插件功能

接下来,你可以在Flutter组件中使用该插件提供的功能。以下是一个简单的示例,假设Fluxivity有一个initialize方法和一个doSomething方法:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Fluxivity Plugin Example'),
        ),
        body: FluxivityExample(),
      ),
    );
  }
}

class FluxivityExample extends StatefulWidget {
  @override
  _FluxivityExampleState createState() => _FluxivityExampleState();
}

class _FluxivityExampleState extends State<FluxivityExample> {
  String result = '';

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

  void _initializeFluxivity() async {
    try {
      // 假设Fluxivity有一个静态的initialize方法
      await Fluxivity.initialize();
      setState(() {
        result = 'Fluxivity initialized!';
      });
      // 调用其他方法
      _doSomething();
    } catch (e) {
      setState(() {
        result = 'Failed to initialize Fluxivity: $e';
      });
    }
  }

  void _doSomething() async {
    try {
      // 假设Fluxivity有一个doSomething方法
      var response = await Fluxivity.doSomething();
      setState(() {
        result = 'doSomething result: $response';
      });
    } catch (e) {
      setState(() {
        result = 'Failed to doSomething: $e';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(result),
          ElevatedButton(
            onPressed: () {
              // 可以在按钮点击时再次调用doSomething
              _doSomething();
            },
            child: Text('Do Something'),
          ),
        ],
      ),
    );
  }
}

注意事项

  1. 插件文档:由于“fluxivity”是一个未知的插件,务必查阅其官方文档或源代码以了解具体的API和使用方法。
  2. 错误处理:在实际项目中,应添加更详细的错误处理逻辑。
  3. 权限:如果插件需要特定的权限(如访问存储、相机等),请确保在AndroidManifest.xmlInfo.plist中正确配置。
  4. 版本兼容性:确保插件版本与你的Flutter SDK版本兼容。

由于“fluxivity”的具体实现未知,上述代码是一个基于假设的示例。在实际使用中,请根据插件的实际API进行调整。

回到顶部