Flutter安全点击防护插件guarded_button的使用

Flutter安全点击防护插件guarded_button的使用

guarded_button 是一个 Flutter 包,它为 Material 按钮添加了防护功能,限制用户交互。

一个带有防护的按钮会在异步回调结束或最小时间过去之前显示 CircularProgressIndicator。最小时间可以在 Guard 构造函数中设置。

目前该包支持 ElevatedButtonOutlinedButtonTextButton

分别添加防护

你可以分别为每个按钮添加单独的防护,使它们独立工作:

[
  GuardedElevatedButton(
    guard: Guard(), // 创建一个新的 Guard 实例
    onPressed: () => {}, // 点击事件
    onLongPress: () => {}, // 长按事件
    child: const Text('Elevated'), // 按钮文本
  ),
  GuardedOutlinedButton(
    guard: Guard(), // 创建一个新的 Guard 实例
    onPressed: () => {}, // 点击事件
    onLongPress: () => {}, // 长按事件
    child: const Text('Outlined'), // 按钮文本
  ),
  GuardedTextButton(
    guard: Guard(), // 创建一个新的 Guard 实例
    onPressed: () => {}, // 点击事件
    onLongPress: () => {}, // 长按事件
    child: const Text('Text'), // 按钮文本
  ),
]

共享同一个防护

你也可以使用同一个防护实例来控制多个按钮的交互:

[
  GuardedElevatedButton(
    guard: guard, // 使用共享的 Guard 实例
    onPressed: () => {}, // 点击事件
    onLongPress: () => {}, // 长按事件
    child: const Text('Elevated'), // 按钮文本
  ),
  GuardedOutlinedButton(
    guard: guard, // 使用共享的 Guard 实例
    onPressed: () => {}, // 点击事件
    onLongPress: () => {}, // 长按事件
    child: const Text('Outlined'), // 按钮文本
  ),
  GuardedTextButton(
    guard: guard, // 使用共享的 Guard 实例
    onPressed: () => {}, // 点击事件
    onLongPress: () => {}, // 长按事件
    child: const Text('Text'), // 按钮文本
  ),
]

对按钮进行样式设置

你可以对按钮进行样式设置:

[
  GuardedElevatedButton(
    guard: Guard(), // 创建一个新的 Guard 实例
    style: ElevatedButton.styleFrom( // 设置背景和前景颜色
      backgroundColor: Colors.orange,
      foregroundColor: Colors.black,
    ),
    onPressed: () => {}, // 点击事件
    onLongPress: () => {}, // 长按事件
    child: const Text('Elevated'), // 按钮文本
  ),
  GuardedOutlinedButton(
    guard: Guard(), // 创建一个新的 Guard 实例
    style: OutlinedButton.styleFrom( // 设置背景和前景颜色
      backgroundColor: Colors.orange,
      foregroundColor: Colors.black,
    ),
    onPressed: () => {}, // 点击事件
    onLongPress: () => {}, // 长按事件
    child: const Text('Outlined'), // 按钮文本
  ),
  GuardedTextButton(
    guard: Guard(), // 创建一个新的 Guard 实例
    style: TextButton.styleFrom( // 设置前景颜色
      foregroundColor: Colors.orange,
    ),
    onPressed: () => {}, // 点击事件
    onLongPress: () => {}, // 长按事件
    child: const Text('Text'), // 按钮文本
  ),
]

完整示例代码

以下是完整的示例代码,展示了如何在 Flutter 应用程序中使用 guarded_button 插件:

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

void main() {
  runApp(
    const MaterialApp(
      title: 'Guarded Button Package Demo',
      home: GuardedButtonDemo(),
    ),
  );
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Guarded Buttons Package Demo'),
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(24.0),
          child: Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const SizedBox(
                    width: 120,
                    child: Text('分别防护:'),
                  ),
                  GuardedElevatedButton(
                    guard: Guard(),
                    onPressed: () => {}, // 点击事件
                    onLongPress: () => {}, // 长按事件
                    child: const Text('Elevated'), // 按钮文本
                  ),
                  GuardedOutlinedButton(
                    guard: Guard(),
                    onPressed: () => {}, // 点击事件
                    onLongPress: () => {}, // 长按事件
                    child: const Text('Outlined'), // 按钮文本
                  ),
                  GuardedTextButton(
                    guard: Guard(),
                    onPressed: () => {}, // 点击事件
                    onLongPress: () => {}, // 长按事件
                    child: const Text('Text'), // 按钮文本
                  ),
                ].map((widget) => Padding(
                  padding: const EdgeInsets.only(right: 16),
                  child: widget,
                )).toList(),
              ),
              Builder(
                builder: (context) {
                  var guard = Guard();

                  return Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const SizedBox(
                        width: 120,
                        child: Text('共用防护:'),
                      ),
                      GuardedElevatedButton(
                        guard: guard,
                        onPressed: () => {}, // 点击事件
                        onLongPress: () => {}, // 长按事件
                        child: const Text('Elevated'), // 按钮文本
                      ),
                      GuardedOutlinedButton(
                        guard: guard,
                        onPressed: () => {}, // 点击事件
                        onLongPress: () => {}, // 长按事件
                        child: const Text('Outlined'), // 按钮文本
                      ),
                      GuardedTextButton(
                        guard: guard,
                        onPressed: () => {}, // 点击事件
                        onLongPress: () => {}, // 长按事件
                        child: const Text('Text'), // 按钮文本
                      ),
                    ].map((widget) => Padding(
                      padding: const EdgeInsets.only(right: 16),
                      child: widget,
                    )).toList(),
                  );
                },
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const SizedBox(
                    width: 120,
                    child: Text('样式设置:'),
                  ),
                  GuardedElevatedButton(
                    guard: Guard(),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.orange,
                      foregroundColor: Colors.black,
                    ),
                    onPressed: () => {}, // 点击事件
                    onLongPress: () => {}, // 长按事件
                    child: const Text('Elevated'), // 按钮文本
                  ),
                  GuardedOutlinedButton(
                    guard: Guard(),
                    style: OutlinedButton.styleFrom(
                      backgroundColor: Colors.orange,
                      foregroundColor: Colors.black,
                    ),
                    onPressed: () => {}, // 点击事件
                    onLongPress: () => {}, // 长按事件
                    child: const Text('Outlined'), // 按钮文本
                  ),
                  GuardedTextButton(
                    guard: Guard(),
                    style: TextButton.styleFrom(
                      foregroundColor: Colors.orange,
                    ),
                    onPressed: () => {}, // 点击事件
                    onLongPress: () => {}, // 长按事件
                    child: const Text('Text'), // 按钮文本
                  ),
                ].map((widget) => Padding(
                  padding: const EdgeInsets.only(right: 16),
                  child: widget,
                )).toList(),
              ),
            ].map((widget) => Padding(
              padding: const EdgeInsets.only(bottom: 16),
              child: widget,
            )).toList(),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter安全点击防护插件guarded_button的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter安全点击防护插件guarded_button的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于Flutter中的guarded_button插件的使用,以下是一个具体的代码示例,展示了如何集成和使用这个插件来增强按钮点击的安全性,防止重复点击。

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

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

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

接下来,在你的Dart文件中使用GuardedButton组件。以下是一个简单的示例:

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

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

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

class MyGuardedButtonWidget extends StatefulWidget {
  @override
  _MyGuardedButtonWidgetState createState() => _MyGuardedButtonWidgetState();
}

class _MyGuardedButtonWidgetState extends State<MyGuardedButtonWidget> {
  // 模拟一个耗时操作,比如网络请求
  Future<void> performAction() async {
    await Future.delayed(Duration(seconds: 2));
    print('Action performed!');
  }

  @override
  Widget build(BuildContext context) {
    return GuardedButton<void>(
      onPressed: performAction,
      loadingBuilder: (context, isLoading) {
        return ElevatedButton(
          onPressed: isLoading ? null : () {}, // 当加载时禁用按钮点击
          child: Text(
            isLoading ? 'Loading...' : 'Click Me',
            style: TextStyle(color: isLoading ? Colors.grey : Colors.white),
          ),
          style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all(
              isLoading ? Colors.grey[300]! : Colors.blue,
            ),
          ),
        );
      },
    );
  }
}

在这个示例中,我们创建了一个GuardedButton,它包装了一个ElevatedButton。当performAction函数被调用时,按钮会进入加载状态(显示"Loading…"并禁用点击)。performAction函数模拟了一个耗时操作,使用Future.delayed来模拟。

关键部分是GuardedButtonloadingBuilder参数,它接收一个函数,该函数根据按钮是否处于加载状态来构建按钮。当isLoadingtrue时,按钮显示"Loading…"文本并禁用点击;当isLoadingfalse时,按钮显示"Click Me"文本并启用点击。

这种方式可以有效地防止按钮在耗时操作期间被重复点击,从而提升用户体验和应用的稳定性。

回到顶部