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

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

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.dartpending_button/pending_button.dart

  2. 创建应用:创建一个基本的Flutter应用,包括MyAppMyHomePage

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

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

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

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

回到顶部