Flutter待确认按钮功能插件pending_button的使用

Flutter待确认按钮功能插件pending_button的使用

pending_button 是一个用于指示异步操作不同状态的基本按钮。它为用户提供加载状态以及操作结果的反馈。

安装

在 pubspec.yaml 文件中添加 pending_button 作为依赖:

dependencies:
  pending_button: 0.0.7

使用

首先,导入包:

import 'package:pending_button/pending_button.dart';

然后,添加 PendingButton 小部件并传递异步函数,无需等待该未来的结果:

PendingButton(
    asynFunction: myFunction,
    child: const Text('Save'),
),

Future<bool> myFunction() =>
    Future.delayed(const Duration(seconds: 2)).then(
        (value) {
          return true;
        },
    );

支持的不同类型按钮

  • PendingButton
  • PendingButton.outlined
  • PendingButton.text
  • PendingButton.icon

错误处理

当发生错误时,可以使用 onError 方法显示 snackbar 或 toast:

PendingButton(
    asynFunction: myFunction,
    onError: (Exception error) {
        ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
                content: Text(error.toString()),
            ),
        );
    },
    child: Text('Authentificate'),
),

Future<void> myFunction() =>
    Future.delayed(const Duration(seconds: 2)).then(
        (value) {
            throw Exception('Authentification fail');
        },
    );

成功响应

onSuccess 方法返回来自未来的响应数据:

PendingButton(
    asynFunction: myFunction,
    onSuccess: (result) {
        debugPrint(result.toString());
    },
    child: Text('Authentificate'),
),

操作前检查

beforeFunction 可以用来在执行主要函数之前检查条件,应返回布尔值:

PendingButton(
    asynFunction: myFunction,
    beforeFunction: () {
        if (password.length < 8) return false;
        if (login.isEmpty) return false;
        return true;
    },
    child: Text('Authentificate'),
),

装饰(可选)

不同的装饰属性可以根据需要进行设置:

属性 默认值 标准 Outline Text Icon
child - Widget Widget Widget Icon
width widget width ✅ ✅ ✅ ✅
height widget height ✅ ✅ ✅ ✅
backgroundColor Primary color ✅ ⛔ ⛔ ⛔
foregroundColor onPrimary ✅ ✅ ✅ ⛔
successColor Green ✅ ✅ ✅ ✅
errorColor Error color ✅ ✅ ✅ ✅
borderColor background or primary ✅ ✅ ⛔ ⛔
borderRadius 10.0 ✅ ✅ ⛔ ⛔
animationDuration 200 milliseconds ✅ ✅ ✅ ✅

示例 Demo

以下是一个完整的示例代码:

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

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late ThemeMode theme;

  @override
  void initState() {
    super.initState();
    theme = ThemeMode.light;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pending Button Demo',
      themeMode: theme,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF00b266),
          brightness: Brightness.light,
        ),
        useMaterial3: true,
      ),
      darkTheme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF00b266),
          brightness: Brightness.dark,
        ),
        useMaterial3: true,
      ),
      home: HomePage(
        isDark: theme == ThemeMode.dark,
        callback: () {
          setState(() {
            theme = (theme == ThemeMode.dark) ? ThemeMode.light : ThemeMode.dark;
          });
        },
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  final bool isDark;
  final VoidCallback callback;
  const HomePage({
    super.key,
    required this.isDark,
    required this.callback,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Pending button'),
        actions: [
          IconButton(
            icon: Icon(
              isDark ? Icons.light_mode_rounded : Icons.dark_mode_rounded,
            ),
            tooltip: 'Theme',
            onPressed: callback,
          ),
          const SizedBox(width: 30),
        ],
      ),
      body: Center(
        child: Column(
          children: [
            PendingButton(
              asynFunction: futureFunction,
              width: 200,
              borderRadius: 15.0,
              backgroundColor: Colors.blueAccent,
              onSuccess: (value) {
                debugPrint(value.toString());
              },
              child: const Text('Filled succes'),
            ),
            PendingButton(
              asynFunction: () {
                return futureFunction2(1, 1, 1, 1, 1, 1, 1, 1, 1);
              },
              width: 200,
              child: const Text('Filled with args'),
            ),
            const SizedBox(height: 10),
            PendingButton(
              asynFunction: futureErrorFunction,
              child: const Text('Short'),
            ),
            const SizedBox(height: 10),
            PendingButton(
              asynFunction: futureErrorFunction,
              child: Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Icon(
                    Icons.login,
                    color: Theme.of(context).colorScheme.onPrimary,
                  ),
                  const SizedBox(width: 20),
                  const Text('Connexion'),
                ],
              ),
            ),
            const SizedBox(height: 10),
            PendingButton.outlined(
              asynFunction: futureErrorFunction,
              child: const Text('Oulined error'),
            ),
            const SizedBox(height: 10),
            PendingButton.outlined(
              asynFunction: futureErrorFunction,
              child: const Text('Oulined Success'),
            ),
            const SizedBox(height: 10),
            PendingButton.text(
              asynFunction: futureFunction,
              child: const Text('Text success'),
            ),
            const SizedBox(height: 10),
            PendingButton.text(
              asynFunction: futureErrorFunction,
              child: const Text('wrong password'),
            ),
            const SizedBox(height: 10),
            PendingButton.icon(
              asynFunction: futureFunction,
              child: const Icon(Icons.add),
            ),
            const SizedBox(height: 10),
            PendingButton.icon(
              asynFunction: myFunction,
              onError: (Exception error) {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(
                    content: Text(error.toString()),
                  ),
                );
              },
              onSuccess: (result) {},
              child: const Icon(Icons.delete),
            ),
            PendingButton.icon(
              asynFunction: () {
                debugPrint('hello');
              },
              child: const Icon(Icons.add),
            ),
          ],
        ),
      ),
    );
  }

  Future<bool> futureFunction() =>
      Future.delayed(const Duration(seconds: 2)).then(
        (value) {
          return true;
        },
      );

  Future<bool> futureFunction2(int text1, int text2, int text3, int text4,
          int text5, int text6, int text7, int text8, int text9) =>
      Future.delayed(const Duration(seconds: 2)).then(
        (value) {
          throw const Failures(message: 'Authentification fail');
        },
      );

  Future<void> futureErrorFunction() =>
      Future.delayed(const Duration(seconds: 2)).then(
        (value) {
          throw const Failures(message: 'Authentification fail');
        },
      );

  Future<void> myFunction() => Future.delayed(const Duration(seconds: 2)).then(
        (value) {
          throw Exception('Authentification fail');
        },
      );
}

class Failures implements Exception {
  final String message;
  const Failures({required this.message});
}

以上代码展示了如何使用 pending_button 插件创建各种类型的按钮,并处理成功和失败的情况。


更多关于Flutter待确认按钮功能插件pending_button的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter待确认按钮功能插件pending_button的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用pending_button插件来实现待确认按钮功能的代码示例。假设你已经通过pubspec.yaml文件添加了pending_button依赖,并且已经运行了flutter pub get来安装它。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  pending_button: ^最新版本号  # 替换为实际可用的最新版本号

2. 导入并使用PendingButton

在你的Dart文件中,导入pending_button包,并使用PendingButton组件。以下是一个完整的示例,展示了如何使用PendingButton:

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

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  bool isLoading = false;

  void handleButtonClick() async {
    setState(() {
      isLoading = true;
    });

    // 模拟一个异步操作,比如网络请求
    await Future.delayed(Duration(seconds: 2));

    // 根据你的需求处理操作完成后的逻辑
    // 例如,显示一个Snackbar或更新UI
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('操作完成!'),
        duration: Duration(seconds: 1),
      ),
    );

    setState(() {
      isLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pending Button Demo'),
      ),
      body: Center(
        child: PendingButton(
          loading: isLoading,
          onPressed: handleButtonClick,
          child: Text('点击我'),
          loadingChild: Text('加载中...'),
        ),
      ),
    );
  }
}

代码解释

  1. 导入依赖:首先,导入flutter/material.dart和pending_button/pending_button.dart。

  2. 创建应用:创建一个基本的Flutter应用,包括MyApp和MyHomePage。

  3. 状态管理:在_MyHomePageState中,定义一个布尔值isLoading来跟踪按钮是否处于加载状态。

  4. 按钮点击处理:在handleButtonClick方法中,将isLoading设置为true,模拟一个异步操作(如网络请求),然后更新UI并重置isLoading为false。

  5. PendingButton使用:在UI中使用PendingButton,并根据isLoading状态显示不同的子组件(默认文本和加载文本)。

这样,你就实现了一个待确认按钮功能,当按钮被点击时,会显示加载状态,直到异步操作完成。希望这个示例对你有所帮助!

回到顶部