Flutter条件使用插件use_in_case的使用

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

Flutter条件使用插件 use_in_case 的使用

简介

use_in_case 是一个 Flutter 插件,用于定义和执行复杂的业务逻辑(Interactors)。它提供了多种类型的 Interactors 和修饰符(Modifiers),可以灵活地定制 Interactors 的执行流程。

特性

  • Interactor 类型:支持多种参数化和结果返回的 Interactor 类型。
  • 修饰符:提供了多种修饰符来增强 Interactor 的功能,如超时、日志记录、异常处理等。
  • 进度 Interactor:支持在执行过程中发布进度信息。

安装

pubspec.yaml 文件中添加依赖:

dependencies:
  use_in_case: ^最新版本号

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

Interactor 类型

类型名称 参数化 结果
ParameterizedResultInteractor
ParameterizedInteractor
ResultInteractor
Interactor

使用方法

定义一个 Interactor

首先,定义一个 Interactor。Interactor 必须实现或扩展上述类型之一。

import 'package:use_in_case/use_in_case.dart';

final class StringToIntConverter implements ParameterizedResultInteractor<String, int> {
  @override
  Future<int> execute(String input) async {
    return int.parse(input);
  }
}

创建并调用 Interactor

创建 Interactor 实例并调用其方法。

void main() async {
  final converter = StringToIntConverter();

  final result = await converter.getOrThrow("123"); // 输出: 123
  print(result);

  final nullResult = await converter.getOrNull("not-a-number"); // 输出: null
  print(nullResult);

  final fallbackResult = await converter.getOrElse("word", (_) async => -1); // 输出: -1
  print(fallbackResult);

  await converter.run("123"); // 输出: 无(void)
}

修饰符

use_in_case 提供了多种修饰符来增强 Interactor 的功能。以下是一些常用的修饰符:

方法名称 描述
getOrThrow 调用 Interactor 并在失败时抛出异常。
getOrNull 调用 Interactor 并在失败时返回 null
getOrElse 调用 Interactor 并在失败时返回一个备用值。
run 调用 Interactor 并忽略结果。

自定义修饰符

可以通过扩展 Interactor 类来定义自定义修饰符。

extension CustomModifier<Input, Output> on ParameterizedResultInteractor<Input, Output> {
  ParameterizedResultInteractor<Input, Output> customModifier() {
    return InlinedParameterizedResultInteractor((input) async {
      print("I am here!");
      return await execute(input);
    });
  }
}

进度 Interactor

在某些情况下,Interactor 可能需要发布进度信息。例如,文件下载 Interactor:

typedef SourceUrl = String;
typedef DestinationFilepath = String;
typedef Parameter = ({ SourceUrl sourceUrl, DestinationFilepath destinationFilepath });

typedef DownloadedBytes = int;
typedef DownloadProgress = int;

final class FileDownloadInteractor extends ParameterizedResultProgressInteractor<Parameter, DownloadedBytes, DownloadProgress> {
  @override
  Future<DownloadedBytes> execute(Parameter input) async {
    await emitProgress(0);

    // 模拟文件下载
    await Future.delayed(Duration(seconds: 2));
    await emitProgress(50);

    await Future.delayed(Duration(seconds: 2));
    await emitProgress(100);

    return 1024; // 假设下载了 1024 字节
  }
}

void main() async {
  final downloadService = FileDownloadInteractor();

  final result = await downloadService
      .receiveProgress((progress) async {
        print('Download-Progress: $progress%');
      })
      .getOrThrow((
        sourceUrl: 'https://example.com/image.jpg',
        destinationFilepath: 'image.jpg'
      ));

  print(result); // 输出: 1024
}

装饰器顺序

装饰器的顺序很重要,它们会按顺序应用到 Interactor 上。例如:

myInteractor
    .intercept((it) => print("Exception caught: $it"))
    .before((it) => print("Interactor called with parameter = $it"))
    .after((it) => println("Output produced: $it"))
    .watchBusyState((it) => println("Busy State: $it"));

完整示例

以下是一个完整的示例,展示了如何定义和使用 use_in_case 中的 Interactor 和修饰符。

import 'package:use_in_case/use_in_case.dart';

// 定义一个 Interactor
final class StringToIntConverter implements ParameterizedResultInteractor<String, int> {
  @override
  Future<int> execute(String input) async {
    return int.parse(input);
  }
}

void main() async {
  final converter = StringToIntConverter();

  // 使用修饰符
  final result = await converter
      .timeout(Duration(seconds: 5))
      .before((input) => print("Trying to convert $input to int."))
      .after((output) => print("Successfully converted int. Result: $output"))
      .intercept((exception) => print("Failed to convert int. Exception caught: $exception"))
      .getOrThrow("123");

  print(result); // 输出: 123

  // 处理失败情况
  final nullResult = await converter.getOrNull("not-a-number");
  print(nullResult); // 输出: null

  final fallbackResult = await converter.getOrElse("word", (_) async => -1);
  print(fallbackResult); // 输出: -1

  // 忽略结果
  await converter.run("123");
}

通过以上示例,您可以了解如何在 Flutter 项目中使用 use_in_case 插件来定义和执行复杂的业务逻辑。希望这对您有所帮助!


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

1 回复

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


当然,use_in_case 是一个 Flutter 插件,用于在特定条件下渲染子组件。这个插件非常有用,因为它允许你根据布尔条件来动态显示或隐藏组件,而无需使用多个 if-else 语句或嵌套的 Builder 组件。

以下是一个简单的示例,展示了如何在 Flutter 中使用 use_in_case 插件。

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

dependencies:
  flutter:
    sdk: flutter
  use_in_case: ^x.y.z  # 请替换为最新版本号

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

接下来,你可以在你的 Flutter 应用中使用 UseInCase 组件。以下是一个完整的示例代码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'UseInCase Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('UseInCase Demo'),
        ),
        body: Center(
          child: UseInCaseDemo(),
        ),
      ),
    );
  }
}

class UseInCaseDemo extends StatefulWidget {
  @override
  _UseInCaseDemoState createState() => _UseInCaseDemoState();
}

class _UseInCaseDemoState extends State<UseInCaseDemo> {
  bool isConditionMet = false;

  void toggleCondition() {
    setState(() {
      isConditionMet = !isConditionMet;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        ElevatedButton(
          onPressed: toggleCondition,
          child: Text('Toggle Condition'),
        ),
        SizedBox(height: 20),
        UseInCase<bool>(
          condition: isConditionMet,
          builder: () => Text(
            'Condition is met!',
            style: TextStyle(fontSize: 24, color: Colors.green),
          ),
          fallback: Text(
            'Condition is not met.',
            style: TextStyle(fontSize: 24, color: Colors.red),
          ),
        ),
      ],
    );
  }
}

在这个示例中:

  1. UseInCaseDemo 是一个有状态的组件,它包含一个布尔变量 isConditionMet
  2. toggleCondition 方法用于切换 isConditionMet 的值。
  3. UseInCase 组件接受一个 condition 参数,该参数是一个布尔值。
  4. 如果 conditiontrueUseInCase 将渲染 builder 参数提供的组件(在这里是显示 “Condition is met!” 的 Text 组件)。
  5. 如果 conditionfalseUseInCase 将渲染 fallback 参数提供的组件(在这里是显示 “Condition is not met.” 的 Text 组件)。

这个示例展示了如何使用 use_in_case 插件来根据条件动态渲染不同的组件。希望这对你有所帮助!

回到顶部