Flutter模态加载按钮插件loading_modal_button的使用

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

Flutter模态加载按钮插件loading_modal_button的使用

该插件允许在按下按钮后,在模态屏幕上指示异步过程。

特性

你可以使用Flutter默认的按钮类型,也可以使用自定义的widget。以下是可使用的按钮类型:

  • ElevatedButton
  • OutlinedButton
  • TextButton
  • IconButton

开始使用

首先,你需要导入该插件:

import 'package:loading_modal_button/loading_modal_button.dart';

基本用法

简单用法

LoadingModalButton(
  onPressed: () async {
    // 异步处理
  },
),

使用默认的Flutter按钮类型

LoadingModalButton(
  buttonType: ButtonType.outlined, // 你可以选择 [ButtonType.elevated], [ButtonType.outlined], [ButtonType.text]
  onPressed: () async {
  },
),

示例代码

以下是一个完整的示例代码,展示了如何使用loading_modal_button插件。

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:loading_modal_button/loading_modal_button.dart';

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

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool material3 = true;
  Color material3Color = Colors.deepPurple;
  MaterialColor material2Color = Colors.blue;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        useMaterial3: material3,
        colorSchemeSeed: material3 ? material3Color : null,
        primarySwatch: material3 ? null : material2Color,
      ),
      home: MyHomePage(
        floatingActionButtonOnPressed: () => setState(() {
          material3 = !material3;
        }),
        material3: material3,
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({
    super.key,
    required this.floatingActionButtonOnPressed,
    required this.material3,
  });
  final VoidCallback floatingActionButtonOnPressed;
  final bool material3;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Loading Modal Button'),
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: floatingActionButtonOnPressed,
        label: Text(material3 ? 'Change To Material 2' : 'Change To Material 3'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(20),
        children: [
          ..._defaultButtonSection(),
          ..._iconButtonSection(),
          ..._callBackSection(context),
          ..._customLoadingSection(),
          const SizedBox(
            height: 80,
          ),
        ],
      ),
    );
  }

  Widget _sectionTitle(String title) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(title),
        const SizedBox(
          height: 10,
        ),
      ],
    );
  }

  List<Widget> _defaultButtonSection() {
    return [
      _sectionTitle('默认按钮'),
      LoadingModalButton(
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 1));
        },
        buttonChild: const Text('Elevated Button'),
      ),
      const SizedBox(
        height: 20,
      ),
      LoadingModalButton(
        buttonType: ButtonType.outlined,
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 1));
        },
        buttonChild: const Text('Outlined Button'),
      ),
      const SizedBox(
        height: 20,
      ),
      LoadingModalButton(
        buttonType: ButtonType.text,
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 1));
        },
        buttonChild: const Text('Text Button'),
      ),
      const SizedBox(
        height: 20,
      ),
    ];
  }

  List<Widget> _iconButtonSection() {
    return [
      _sectionTitle('图标按钮'),
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          LoadingModalButton(
            onPressed: () async {
              await Future.delayed(const Duration(seconds: 1));
            },
            iconChild: const Icon(
              Icons.flutter_dash,
            ),
          ),
          LoadingModalButton(
            onPressed: () async {
              await Future.delayed(const Duration(seconds: 1));
            },
            iconChild: const Icon(
              Icons.flutter_dash,
            ),
            iconButtonWithModalStyle: const IconButtonWithModalStyle(
              iconSize: 35,
              color: Colors.red,
            ),
          ),
          LoadingModalButton(
            onPressed: () async {
              await Future.delayed(const Duration(seconds: 1));
            },
            iconChild: const Icon(
              Icons.flutter_dash_rounded,
            ),
            iconButtonWithModalStyle: const IconButtonWithModalStyle(
              iconSize: 45,
              color: Colors.blue,
            ),
          ),
          LoadingModalButton(
            onPressed: () async {
              await Future.delayed(const Duration(seconds: 1));
            },
            iconChild: const Icon(
              Icons.flutter_dash_sharp,
            ),
            iconButtonWithModalStyle: const IconButtonWithModalStyle(
              iconSize: 55,
              color: Colors.green,
            ),
          ),
        ],
      ),
      const SizedBox(
        height: 20,
      ),
    ];
  }

  List<Widget> _callBackSection(BuildContext context) {
    return [
      _sectionTitle('异步函数回调'),
      LoadingModalButton(
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 1));
        },
        afterAsync: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (_) => const NextPage(),
            ),
          );
        },
        buttonChild: const Text('1秒后跳转到下一页'),
      ),
      const SizedBox(
        height: 20,
      ),
      LoadingModalButton(
        buttonType: ButtonType.outlined,
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 1));
        },
        afterAsync: () {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('SnackBar'),
            ),
          );
        },
        buttonChild: const Text('1秒后显示SnackBar'),
      ),
      const SizedBox(
        height: 20,
      ),
      LoadingModalButton(
        buttonType: ButtonType.text,
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 1));
        },
        afterAsync: () {
          showDialog(
            context: context,
            builder: (_) => AlertDialog(
              title: const Text('AlertDialog'),
              actions: [
                TextButton(
                  child: const Text('OK'),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
              ],
            ),
          );
        },
        buttonChild: const Text('1秒后显示AlertDialog'),
      ),
      const SizedBox(
        height: 20,
      ),
      LoadingModalButton(
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 1));
        },
        afterAsync: () {
          showDialog(
            context: context,
            builder: (_) => const SimpleDialog(
              title: Text('SimpleDialog'),
              contentPadding: EdgeInsets.all(24),
              children: [
                Text('Child 1'),
                Text('Child 2'),
                Text('Child 3'),
              ],
            ),
          );
        },
        buttonChild: const Text('1秒后显示SimpleDialog'),
      ),
      const SizedBox(
        height: 20,
      ),
      LoadingModalButton(
        buttonType: ButtonType.outlined,
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 1));
        },
        afterAsync: () {
          showCupertinoDialog(
            context: context,
            builder: (_) => CupertinoAlertDialog(
              title: const Text('CupertinoAlertDialog'),
              actions: [
                CupertinoDialogAction(
                  child: const Text('OK'),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
              ],
            ),
          );
        },
        buttonChild: const Text('1秒后显示CupertinoAlertDialog'),
      ),
      const SizedBox(
        height: 20,
      ),
    ];
  }

  List<Widget> _customLoadingSection() {
    return [
      _sectionTitle('自定义加载组件'),
      LoadingModalButton(
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 2));
        },
        buttonChild: const Text('红色圆形进度条'),
        customLoadingWidget: const CircularProgressIndicator(
          color: Colors.red,
        ),
      ),
      const SizedBox(
        height: 20,
      ),
      LoadingModalButton(
        onPressed: () async {
          await Future.delayed(const Duration(seconds: 2));
        },
        buttonType: ButtonType.outlined,
        buttonChild: const Text('线性进度条'),
        customLoadingWidget: const LinearProgressIndicator(),
      ),
      const SizedBox(
        height: 20,
      ),
    ];
  }
}

class NextPage extends StatelessWidget {
  const NextPage({super.key});
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('下一页'),
      ),
      body: const Center(
        child: Text('下一页'),
      ),
    );
  }
}

更多关于Flutter模态加载按钮插件loading_modal_button的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter模态加载按钮插件loading_modal_button的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用loading_modal_button插件的一个示例代码案例。这个插件允许你创建一个模态加载按钮,当按钮被点击时,会显示一个加载指示器,直到操作完成。

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

dependencies:
  flutter:
    sdk: flutter
  loading_modal_button: ^0.1.0  # 请注意版本号,根据实际情况选择最新版本

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

接下来是一个完整的示例代码,展示了如何使用LoadingModalButton

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter 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 handleButtonPress() async {
    setState(() {
      isLoading = true;
    });

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

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

    // 这里可以添加操作完成后的逻辑,例如显示一个Snackbar
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('操作完成!')),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Loading Modal Button Demo'),
      ),
      body: Center(
        child: LoadingModalButton(
          child: Text('点击加载'),
          loadingText: '加载中...',
          color: Colors.blue,
          loadingColor: Colors.grey,
          onPress: handleButtonPress,
          isLoading: isLoading,
        ),
      ),
    );
  }
}

在这个示例中:

  1. LoadingModalButton是一个自定义的按钮,它有两个状态:加载中和非加载中。
  2. child参数是按钮在非加载状态下的文本或子组件。
  3. loadingText参数是按钮在加载状态下的文本。
  4. color参数是按钮在非加载状态下的颜色。
  5. loadingColor参数是按钮背景在加载状态下的颜色(注意:这个参数可能因插件版本而异,请参考最新的文档)。
  6. onPress参数是一个函数,当按钮被点击时调用。
  7. isLoading参数是一个布尔值,用于指示按钮当前是否处于加载状态。

当用户点击按钮时,handleButtonPress函数会被调用,将isLoading设置为true,模拟一个异步操作(使用Future.delayed),然后在操作完成后将isLoading设置为false,并显示一个Snackbar。

希望这个示例对你有帮助!如果你有任何其他问题,请随时提问。

回到顶部