Flutter进度状态按钮插件sp_progress_state_button的使用

Flutter进度状态按钮插件sp_progress_state_button的使用

Fork & 可定制的进度状态按钮。

  • 添加长按功能

安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  sp_progress_state_button: "^1.0.0"

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

使用

图标按钮

ProgressButton.icon(
  iconedButtons: {
    ButtonState.idle: IconedButton(
      text: "发送",
      icon: Icon(Icons.send, color: Colors.white),
      color: Colors.deepPurple.shade500,
    ),
    ButtonState.loading: IconedButton(
      text: "加载中",
      color: Colors.deepPurple.shade700,
    ),
    ButtonState.fail: IconedButton(
      text: "失败",
      icon: Icon(Icons.cancel, color: Colors.white),
      color: Colors.red.shade300,
    ),
    ButtonState.success: IconedButton(
      text: "成功",
      icon: Icon(Icons.check_circle, color: Colors.white),
      color: Colors.green.shade400,
    ),
  },
  onPressed: onPressed,
  state: ButtonState.idle,
);

自定义组件

ProgressButton(
  stateWidgets: {
    ButtonState.idle: Text("空闲", style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500)),
    ButtonState.loading: Text("加载中", style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500)),
    ButtonState.fail: Text("失败", style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500)),
    ButtonState.success: Text("成功", style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500)),
  },
  stateColors: {
    ButtonState.idle: Colors.grey.shade400,
    ButtonState.loading: Colors.blue.shade300,
    ButtonState.fail: Colors.red.shade300,
    ButtonState.success: Colors.green.shade400,
  },
  onPressed: onPressed,
  state: ButtonState.idle,
);

构造函数

ProgressButton 默认构造函数

ProgressButton({
  Map<ButtonState, Widget> stateWidgets, // 状态对应的组件
  Map<ButtonState, Color> stateColors, // 状态对应的颜色
  ButtonState state = ButtonState.idle, // 当前状态
  VoidCallback onPressed, // 按钮点击事件
  VoidCallback onAnimationEnd, // 动画结束回调
  double minWidth = 200.0, // 加载状态最小宽度
  double maxWidth = 400.0, // 其他状态最大宽度
  double radius = 16.0, // 圆角半径
  double height = 53.0, // 高度
  Widget circularProgressIndicator, // 进度指示器,默认为当前状态颜色的圆形进度条
  MainAxisAlignment progressIndicatorAlignment = MainAxisAlignment.spaceBetween, // 进度指示器对齐方式
  double progressIndicatorSize = 35.0, // 进度指示器大小
  EdgeInsets padding = EdgeInsets.zero, // 内边距
  List<ButtonState> minWidthStates, // 最小宽度状态列表,默认为加载状态
  Duration animationDuration, // 动画持续时间
});

ProgressButton.icon 特定构造函数

ProgressButton.icon({
  Map<ButtonState, IconedButton> iconedButtons, // 状态与图标按钮映射
  double iconPadding = 4.0, // 图标内边距
  TextStyle textStyle, // 文本样式
  VoidCallback onPressed, // 按钮点击事件
  ButtonState state = ButtonState.idle, // 当前状态
  EdgeInsets padding = EdgeInsets.zero, // 内边距
});

完整示例

import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:sp_progress_state_button/iconed_button.dart';
import 'package:sp_progress_state_button/progress_button.dart';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '进度按钮示例',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: ProgressButtonHomePage(title: '进度按钮'),
    );
  }
}

class ProgressButtonHomePage extends StatefulWidget {
  ProgressButtonHomePage({Key key, this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  _ProgressButtonHomePageState createState() => _ProgressButtonHomePageState();
}

class _ProgressButtonHomePageState extends State<ProgressButtonHomePage> {
  ButtonState stateOnlyText = ButtonState.idle;
  ButtonState stateOnlyCustomIndicatorText = ButtonState.idle;
  ButtonState stateTextWithIcon = ButtonState.idle;
  ButtonState stateTextWithIconMinWidthState = ButtonState.idle;

  Widget buildCustomButton() {
    var progressTextButton = ProgressButton(
      stateWidgets: {
        ButtonState.idle: Text(
          "空闲",
          style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
        ),
        ButtonState.loading: Text(
          "加载中",
          style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
        ),
        ButtonState.fail: Text(
          "失败",
          style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
        ),
        ButtonState.success: Text(
          "成功",
          style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
        )
      },
      stateColors: {
        ButtonState.idle: Colors.grey.shade400,
        ButtonState.loading: Colors.blue.shade300,
        ButtonState.fail: Colors.red.shade300,
        ButtonState.success: Colors.green.shade400,
      },
      onPressed: onPressedCustomButton,
      state: stateOnlyText,
      padding: EdgeInsets.all(8.0),
    );
    return progressTextButton;
  }

  Widget buildCustomProgressIndicatorButton() {
    var progressTextButton = ProgressButton(
      stateWidgets: {
        ButtonState.idle: Text(
          "空闲",
          style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
        ),
        ButtonState.loading: Text(
          "加载中",
          style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
        ),
        ButtonState.fail: Text(
          "失败",
          style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
        ),
        ButtonState.success: Text(
          "成功",
          style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
        )
      },
      progressIndicator:  CircularProgressIndicator(
        backgroundColor: Colors.white,
        valueColor: AlwaysStoppedAnimation(Colors.red),
        strokeWidth: 1,
      ),
      stateColors: {
        ButtonState.idle: Colors.grey.shade400,
        ButtonState.loading: Colors.blue.shade300,
        ButtonState.fail: Colors.red.shade300,
        ButtonState.success: Colors.green.shade400,
      },
      onPressed: onPressedCustomIndicatorButton,
      state: stateOnlyCustomIndicatorText,
      padding: EdgeInsets.all(8.0),
    );
    return progressTextButton;
  }

  Widget buildTextWithIcon() {
    return ProgressButton.icon(
      iconedButtons: {
        ButtonState.idle: IconedButton(
            text: "发送",
            icon: Icon(Icons.send, color: Colors.white),
            color: Colors.deepPurple.shade500),
        ButtonState.loading:
            IconedButton(text: "加载中", color: Colors.deepPurple.shade700),
        ButtonState.fail: IconedButton(
            text: "失败",
            icon: Icon(Icons.cancel, color: Colors.white),
            color: Colors.red.shade300),
        ButtonState.success: IconedButton(
            text: "成功",
            icon: Icon(Icons.check_circle, color: Colors.white),
            color: Colors.green.shade400)
      },
      onPressed: onPressedIconWithText,
      state: stateTextWithIcon,
    );
  }

  Widget buildTextWithIconWithMinState() {
    return ProgressButton.icon(
      iconedButtons: {
        ButtonState.idle: IconedButton(
            text: "发送",
            icon: Icon(Icons.send, color: Colors.white),
            color: Colors.deepPurple.shade500),
        ButtonState.loading:
            IconedButton(text: "加载中", color: Colors.deepPurple.shade700),
        ButtonState.fail: IconedButton(
            text: "失败",
            icon: Icon(Icons.cancel, color: Colors.white),
            color: Colors.red.shade300),
        ButtonState.success: IconedButton(
            icon: Icon(Icons.check_circle, color: Colors.white),
            color: Colors.green.shade400)
      },
      onPressed: onPressedIconWithMinWidthStateText,
      state: stateTextWithIconMinWidthState,
      minWidthStates: [ButtonState.loading, ButtonState.success],
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            buildCustomButton(),
            SizedBox(height: 32),
            buildTextWithIcon(),
            SizedBox(height: 32),
            buildTextWithIconWithMinState(),
            SizedBox(height: 32),
            buildCustomProgressIndicatorButton()
          ],
        ),
      ),
    );
  }

  void onPressedCustomButton() {
    setState(() {
      switch (stateOnlyText) {
        case ButtonState.idle:
          stateOnlyText = ButtonState.loading;
          break;
        case ButtonState.loading:
          stateOnlyText = ButtonState.fail;
          break;
        case ButtonState.success:
          stateOnlyText = ButtonState.idle;
          break;
        case ButtonState.fail:
          stateOnlyText = ButtonState.success;
          break;
      }
    });
  }

  void onPressedCustomIndicatorButton() {
    setState(() {
      switch (stateOnlyCustomIndicatorText) {
        case ButtonState.idle:
          stateOnlyCustomIndicatorText = ButtonState.loading;
          break;
        case ButtonState.loading:
          stateOnlyCustomIndicatorText = ButtonState.fail;
          break;
        case ButtonState.success:
          stateOnlyCustomIndicatorText = ButtonState.idle;
          break;
        case ButtonState.fail:
          stateOnlyCustomIndicatorText = ButtonState.success;
          break;
      }
    });
  }

  void onPressedIconWithText() async {
    switch (stateTextWithIcon) {
      case ButtonState.idle:
        stateTextWithIcon = ButtonState.loading;
        Future.delayed(Duration(seconds: 1), () {
          setState(() {
            stateTextWithIcon = Random.secure().nextBool()
                ? ButtonState.success
                : ButtonState.fail;
          });
        });

        break;
      case ButtonState.loading:
        break;
      case ButtonState.success:
        stateTextWithIcon = ButtonState.idle;
        break;
      case ButtonState.fail:
        stateTextWithIcon = ButtonState.idle;
        break;
    }
    setState(() {
      stateTextWithIcon = stateTextWithIcon;
    });
  }

  void onPressedIconWithMinWidthStateText() {
    switch (stateTextWithIconMinWidthState) {
      case ButtonState.idle:
        stateTextWithIconMinWidthState = ButtonState.loading;
        Future.delayed(Duration(seconds: 1), () {
          setState(() {
            stateTextWithIconMinWidthState = Random.secure().nextBool()
                ? ButtonState.success
                : ButtonState.fail;
          });
        });

        break;
      case ButtonState.loading:
        break;
      case ButtonState.success:
        stateTextWithIconMinWidthState = ButtonState.idle;
        break;
      case ButtonState.fail:
        stateTextWithIconMinWidthState = ButtonState.idle;
        break;
    }
    setState(() {
      stateTextWithIconMinWidthState = stateTextWithIconMinWidthState;
    });
  }
}

更多关于Flutter进度状态按钮插件sp_progress_state_button的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


sp_progress_state_button 是一个用于 Flutter 的插件,它提供了一个带有进度状态的按钮。这个按钮可以在不同的状态之间切换,例如加载、成功、失败等。通过这个插件,你可以轻松地在按钮中显示进度状态,而不需要手动管理这些状态。

安装

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

dependencies:
  flutter:
    sdk: flutter
  sp_progress_state_button: ^1.0.0  # 请检查最新版本

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

基本用法

以下是一个简单的示例,展示如何使用 sp_progress_state_button

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

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

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

class ProgressStateButtonExample extends StatefulWidget {
  @override
  _ProgressStateButtonExampleState createState() =>
      _ProgressStateButtonExampleState();
}

class _ProgressStateButtonExampleState extends State<ProgressStateButtonExample> {
  ProgressState _state = ProgressState.normal;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ProgressStateButton(
          state: _state,
          onPressed: () async {
            setState(() => _state = ProgressState.loading);
            await Future.delayed(Duration(seconds: 2));
            setState(() => _state = ProgressState.success);
            await Future.delayed(Duration(seconds: 2));
            setState(() => _state = ProgressState.normal);
          },
          normalText: 'Submit',
          loadingText: 'Loading...',
          successText: 'Success!',
          failedText: 'Failed!',
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () {
            setState(() => _state = ProgressState.failed);
          },
          child: Text('Simulate Failure'),
        ),
      ],
    );
  }
}

参数说明

  • state: 按钮的当前状态,类型为 ProgressState,可以是 normalloadingsuccessfailed
  • onPressed: 当按钮被点击时触发的回调函数。
  • normalText: 按钮在正常状态下的文本。
  • loadingText: 按钮在加载状态下的文本。
  • successText: 按钮在成功状态下的文本。
  • failedText: 按钮在失败状态下的文本。

状态切换

在上面的示例中,我们通过 setState 来切换按钮的状态。当按钮被点击时,首先进入 loading 状态,然后模拟一个异步操作(例如网络请求),最后根据操作结果切换到 successfailed 状态。

自定义样式

你可以通过 ProgressStateButton 的其他属性来自定义按钮的样式,例如颜色、大小、圆角等。

ProgressStateButton(
  state: _state,
  onPressed: () async {
    setState(() => _state = ProgressState.loading);
    await Future.delayed(Duration(seconds: 2));
    setState(() => _state = ProgressState.success);
  },
  normalText: 'Submit',
  loadingText: 'Loading...',
  successText: 'Success!',
  failedText: 'Failed!',
  normalBackgroundColor: Colors.blue,
  loadingBackgroundColor: Colors.grey,
  successBackgroundColor: Colors.green,
  failedBackgroundColor: Colors.red,
  borderRadius: BorderRadius.circular(10),
  padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
)
回到顶部