Flutter命令执行插件simple_command的使用

Flutter命令执行插件simple_command的使用

简介

simple_command 是一个简单的 Flutter 包,用于将方法执行包装在 Command 对象中。

同步命令

RelayCommand

这些命令包装了一个同步方法并执行它。

import 'package:simple_command/commands.dart';

final RelayCommand<void> loginCommand = RelayCommand.withoutParam(_onLogin);

void _onLogin() { }

// 调用命令
loginCommand.call();

// 或者直接调用
loginCommand();

你也可以传递参数:

final RelayCommand<String> loginCommand = RelayCommand.withParam(_onLogin);

void _onLogin(String a) { }

// 调用命令并传递参数
loginCommand.call("someParam");

// 或者直接调用并传递参数
loginCommand("someParam");

TwoWayCommand

如果你想让命令返回一个值,可以使用这个命令。

final TwoWayCommand<void, String> loginCommand = TwoWayCommand.withoutParam(_onLogin);

String _onLogin() {
  return 'some result';
}

// 调用命令并获取返回值
final result = loginCommand();

你也可以传递参数:

final TwoWayCommand<Object, String> loginCommand = TwoWayCommand.withParam(_onLogin);

String _onLogin(Object param) {
  return param.toString();
}

// 调用命令并传递参数
final result = loginCommand(someParam);

异步命令

AsyncRelayCommand

这些命令包装了一个异步方法并执行它。

import 'package:simple_command/commands.dart';

final AsyncRelayCommand<void> loginCommand = AsyncRelayCommand.withoutParam(_onLogin);

Future<void> _onLogin() async { }

// 调用命令
await loginCommand.call();

// 或者直接调用
await loginCommand();

你也可以传递参数:

final AsyncRelayCommand<String> loginCommand = AsyncRelayCommand.withParam(_onLogin);

Future<void> _onLogin(String param) async { }

// 调用命令并传递参数
await loginCommand.call(someParam);

// 或者直接调用并传递参数
await loginCommand(someParam);

AsyncTwoWayCommand

如果你想让命令返回一个值,可以使用这个命令。

final AsyncTwoWayCommand<void, String> loginCommand = AsyncTwoWayCommand.withoutParam(_onLogin);

Future<String> _onLogin() async {
  return 'some result';
}

// 调用命令并获取返回值
final result = await loginCommand();

你也可以传递参数:

final AsyncTwoWayCommand<String, String> loginCommand = AsyncTwoWayCommand.withParam(_onLogin);

Future<String> _onLogin(String param) async {
  return 'some result';
}

// 调用命令并传递参数
final result = await loginCommand(someParam);

其他特性

禁用命令

你可以通过设置 canExecute 的值来禁用命令的执行:

final RelayCommand<void> loginCommand = RelayCommand.withoutParam(...);

loginCommand.canExecute.value = false;

检查异步命令是否完成

你可以通过检查 isExecuting 的值来判断一个异步命令是否正在执行。这对于在命令执行时显示加载指示器非常有用:

final AsyncRelayCommand<void> loginCommand = AsyncRelayCommand.withParam(...);

ElevatedButton(
  onPressed: loginCommand,
  child: ValueListenableBuilder<bool>(
    valueListenable: loginCommand.isExecuting,
    builder: (context, isExecuting, _) {
      if (isExecuting) {
        return SizedBox(
          height: 24,
          width: 24,
          child: CircularProgressIndicator(),
        );
      }

      return const Text('Login');
    },
  ),
);

注意事项

传递空参数给非空参数接受命令

final RelayCommand<String> command = RelayCommand.withParam(_onExecute);

// 错误的方式
void _onExecute(String param) { }

// 这将会抛出错误
command.call(null);

// 正确的方式
void _onExecute(String? param) { }

禁用返回值的异步命令

当你将 isExecuting 设置为 false 时,调用返回值的异步命令将会返回 null

完整示例

以下是一个完整的示例,展示了如何使用 simple_command 包。

import 'package:flutter/material.dart';
import 'package:simple_command/commands.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;
  final MyHomeViewModel viewModel = MyHomeViewModel();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'You have pushed the button this many times:',
            ),
            ValueListenableBuilder<int>(
              valueListenable: viewModel.counter,
              builder: (context, counter, child) {
                return Text(
                  '$counter',
                  style: Theme.of(context).textTheme.headline4,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          FloatingActionButton(
            onPressed: viewModel.incrementCounterCommand,
            tooltip: 'Increment',
            child: const Icon(Icons.add),
          ),
          FloatingActionButton(
            onPressed: viewModel.decrementCounterCommand,
            tooltip: 'Decrement',
            child: const Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}

class MyHomeViewModel {
  final ValueNotifier<int> counter = ValueNotifier(0);

  late final RelayCommand incrementCounterCommand = RelayCommand.withoutParam(_incrementCounter);

  late final RelayCommand decrementCounterCommand = RelayCommand.withoutParam(_decrementCounter);

  void _incrementCounter() {
    counter.value++;

    if (counter.value > 4) {
      incrementCounterCommand.canExecute.value = false;
    } else {
      decrementCounterCommand.canExecute.value = true;
    }
  }

  void _decrementCounter() {
    counter.value--;

    if (counter.value <= 5 && counter.value > 0) {
      incrementCounterCommand.canExecute.value = true;
    } else {
      decrementCounterCommand.canExecute.value = false;
    }
  }
}

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

1 回复

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


当然,simple_command 是一个 Flutter 插件,用于在 Flutter 应用中执行系统命令。下面是一个关于如何使用 simple_command 插件的示例代码案例。

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

dependencies:
  flutter:
    sdk: flutter
  simple_command: ^latest_version  # 请替换为实际的最新版本号

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

接下来是一个完整的 Flutter 应用示例,展示了如何使用 simple_command 插件来执行一个简单的系统命令(例如,列出当前目录的文件):

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Simple Command Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _output = '';
  String _error = '';

  Future<void> _execCommand() async {
    setState(() {
      _output = '';
      _error = '';
    });

    try {
      // 这里以列出当前目录文件为例(在Linux/macOS上可以使用 'ls',在Windows上可以使用 'dir')
      String command = Platform.isWindows ? 'dir' : 'ls';
      var result = await SimpleCommand.run(command);

      setState(() {
        _output = result.stdout;
      });
    } catch (e) {
      setState(() {
        _error = e.toString();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Simple Command Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Command Output:', style: TextStyle(fontSize: 18)),
            SizedBox(height: 16),
            Expanded(
              child: SingleChildScrollView(
                child: Text(
                  _output,
                  style: TextStyle(fontSize: 16),
                ),
              ),
            ),
            if (_error.isNotEmpty) ...[
              SizedBox(height: 16),
              Text('Error:', style: TextStyle(fontSize: 18, color: Colors.red)),
              SizedBox(height: 8),
              Text(
                _error,
                style: TextStyle(fontSize: 16, color: Colors.red),
              ),
            ],
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _execCommand,
        tooltip: 'Execute Command',
        child: Icon(Icons.play_arrow),
      ),
    );
  }
}

在这个示例中:

  1. MyAppMyHomePage 是 Flutter 应用的基本结构。
  2. _execCommand 方法使用 SimpleCommand.run 来执行系统命令。
  3. 根据平台的不同(Windows 或其他),命令被设置为 dirls
  4. 命令的输出被显示在屏幕上,如果有错误,错误信息也会被显示。

运行这个应用,点击浮动按钮(FAB)将会执行命令并显示输出。注意,这个示例中的命令(dirls)是在开发者的本地环境中执行的,所以输出内容将取决于你的本地文件系统。

确保在发布应用时,对命令执行进行充分的安全检查,避免潜在的安全风险。

回到顶部