Flutter命令执行插件get_command的使用

Flutter命令执行插件get_command的使用

本库帮助在执行控制器函数时向用户提供反馈。它旨在与Get库一起使用。

让我们创建一个示例来展示其用法:

步骤1:创建带有异步函数longRunningTask的控制器

import 'package:get/get.dart';

class HomeController extends GetxController {
  // 定义一个可观察变量
  final count = 0.obs;

  [@override](/user/override)
  void onInit() {
    super.onInit();
  }

  [@override](/user/override)
  void onReady() {
    super.onReady();
  }

  [@override](/user/override)
  void onClose() {}

  // 模拟耗时任务的异步函数
  Future<void> longRunningTask() async {
    await Future.delayed(Duration(seconds: 1));
    count.value++;
  }
}

步骤2:创建一个简单的视图

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

import '../controllers/home_controller.dart';

class HomeView extends GetView<HomeController> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('HomeView'),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 显示当前计数
            Obx(() {
              return Text("Current value: ${controller.count}");
            }),
            // 按钮用于触发长耗时任务
            ElevatedButton(
                child: const Text("Start long running task"),
                onPressed: controller.longRunningTask),
          ],
        ),
      ),
    );
  }
}

问题:

上述代码的问题在于用户可以在longRunningTask正在执行时再次点击按钮。

扩展控制器以使用GetCommand

import 'dart:async';

import 'package:get/get.dart';
import 'package:get_command/get_command.dart';

class HomeController extends GetxController {
  // 定义可观察变量
  final count = 0.obs;
  // 创建GetCommand实例
  final GetCommand cmdLongRunningTask = GetCommand();

  HomeController() {
    // 将命令函数设置为_longRunningTask
    cmdLongRunningTask.commandFunc = _longRunningTask;
  }

  [@override](/user/override)
  void onInit() {
    super.onInit();
  }

  [@override](/user/override)
  void onReady() {
    super.onReady();
  }

  [@override](/user/override)
  void onClose() {
    // 在关闭时释放资源
    cmdLongRunningTask.dispose();
  }

  // 长耗时任务函数
  FutureOr<void> _longRunningTask() async {
    await Future.delayed(Duration(seconds: 1));
    count.value++;
  }
}

主要变化:

  1. 新增字段 final GetCommand cmdLongRunningTask = GetCommand();
  2. 在构造函数中设置 cmdLongRunningTask.commandFunc = _longRunningTask;
  3. onClose()中调用 cmdLongRunningTask.dispose() 释放资源。

更新HomeView以使用命令

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_command_example/app/modules/home/controllers/home_controller.dart';

class HomeView extends GetView<HomeController> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('HomeView'),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Obx(() {
              return Text("Current value: ${controller.count}");
            }),
            // 动态更新按钮状态
            Obx(() {
              return ElevatedButton(
                onPressed: controller.cmdLongRunningTask.canBeExecuted
                    ? controller.cmdLongRunningTask.exec
                    : null,
                child: controller.cmdLongRunningTask.executing
                    ? Row(mainAxisSize: MainAxisSize.min, children: [
                        const Text('Executing'),
                        const CircularProgressIndicator(),
                      ])
                    : const Text('Call computation'),
              );
            }),
          ],
        ),
      ),
    );
  }
}

效果:

  • 按钮会在任务执行时变为不可用,并显示一个小动画。
  • 如果任务抛出异常,可以通过errorMessage属性显示错误信息。

异常处理

自动捕获异常

如果任务抛出异常,GetCommand会自动捕获并设置errorMessage属性,同时将hasErrorMessage设置为true

示例代码:

FutureOr<void> _longRunningTask() async {
  await Future.delayed(Duration(seconds: 1));
  throw Exception('Ups :-(');
  count.value++;
}

在视图中显示错误消息:

Obx(() {
  return Text(
      "hasErrorMessage: ${controller.cmdLongRunningTask.hasErrorMessage}");
}),

Obx(() {
  return Text(
      "errorMessage: ${controller.cmdLongRunningTask.errorMessage}");
}),

手动处理异常

在任务中手动捕获异常并设置错误消息:

FutureOr<void> _longRunningTask() async {
  try {
    await Future.delayed(Duration(seconds: 1));
    throw Exception('Ups :-(');
    count.value++;
  } on Exception catch (e) {
    cmdLongRunningTask.setState(errorMessage: 'Something went wrong, try again.');
  }
}

使用自定义错误消息提供器

定义一个ErrorMessageProvider回调函数:

typedef ErrorMessageProvider = FutureOr<String> Function(Exception exception);

FutureOr<String> _getErrorMessageFor(Exception exception) {
  String errorMessage = '';

  switch (exception.runtimeType) {
    case OhNoException:
      errorMessage = 'Oh no - what a mess, try again.';
      break;
    default:
      errorMessage = 'Something went wrong :-(';
  }

  return errorMessage;
}

在控制器中使用该回调函数:

HomeController() {
  cmdLongRunningTask.commandFunc = _longRunningTask;
  cmdLongRunningTask.errorMessageProviderFunc = _getErrorMessageFor;
}

示例完整代码

HomeController

import 'dart:async';

import 'package:get/get.dart';
import 'package:get_command/get_command.dart';

class HomeController extends GetxController {
  final computationResult = 0.obs;
  final GetCommand cmdExecuteComputation = GetCommand();

  int _timesCalled = 41;

  HomeController() {
    cmdExecuteComputation.commandFunc = _longRunningComputation;
  }

  [@override](/user/override)
  void onClose() {
    cmdExecuteComputation.dispose();
    super.onClose();
  }

  FutureOr<void> _longRunningComputation() async {
    await Future.delayed(Duration(seconds: 1));
    computationResult.value = _timesCalled++;
  }
}

HomeView

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_command_example/app/modules/home/controllers/home_controller.dart';

class HomeView extends GetView<HomeController> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('HomeView'),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Service Value:'),
            Obx(() {
              return Text(
                '${controller.computationResult}',
                style: TextStyle(fontSize: 20),
              );
            }),
            Obx(() {
              return ElevatedButton(
                onPressed: controller.cmdExecuteComputation.canBeExecuted
                    ? cmdExecuteComputation.exec
                    : null,
                child: controller.cmdExecuteComputation.executing
                    ? Row(mainAxisSize: MainAxisSize.min, children: [
                        const Text('Executing'),
                        CircularProgressIndicator(),
                      ])
                    : const Text('Call computation'),
              );
            }),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter命令执行插件get_command的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


get_commandGetX 库中的一个插件,用于在 Flutter 应用中执行命令。GetX 是一个轻量级且功能强大的 Flutter 状态管理库,提供了路由管理、依赖注入、状态管理等功能。get_command 插件可以帮助你更方便地管理和执行命令。

安装 GetXget_command

首先,你需要在 pubspec.yaml 文件中添加 GetXget_command 的依赖:

dependencies:
  flutter:
    sdk: flutter
  get: ^4.6.5
  get_command: ^1.0.0

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

使用 get_command

get_command 的主要用途是帮助你管理和执行命令。你可以通过 GetCommand 类来创建命令,并在需要时执行它们。

1. 创建一个命令

首先,你需要创建一个命令类,继承自 GetCommand

import 'package:get_command/get_command.dart';

class MyCommand extends GetCommand {
  @override
  void execute() {
    // 在这里编写命令的执行逻辑
    print('MyCommand executed!');
  }
}

2. 执行命令

你可以在任何地方创建并执行这个命令:

void main() {
  final myCommand = MyCommand();
  myCommand.execute(); // 输出: MyCommand executed!
}

3. 传递参数

你还可以在命令中传递参数:

class MyCommand extends GetCommand {
  final String message;

  MyCommand(this.message);

  @override
  void execute() {
    print('MyCommand executed with message: $message');
  }
}

void main() {
  final myCommand = MyCommand('Hello, World!');
  myCommand.execute(); // 输出: MyCommand executed with message: Hello, World!
}

4. 使用 GetCommand 进行依赖注入

GetX 提供了依赖注入的功能,你可以将命令注册为依赖,并在需要时获取它:

import 'package:get/get.dart';

void main() {
  Get.put(MyCommand('Hello, World!'));

  final myCommand = Get.find<MyCommand>();
  myCommand.execute(); // 输出: MyCommand executed with message: Hello, World!
}
回到顶部