flutter 实现时间流失效果

这篇具有很好参考价值的文章主要介绍了flutter 实现时间流失效果。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用 flutter 进度条组件和 RotatedBox 旋转组件,实现时间流失进度条

进度条组件LinearProgressIndicator

属性说明:

value  0-1 之间 进度

RotatedBox 组件

quarterTurns 属性表示象限

quarterTurns: 0 水平

quarterTurns: 1  顺时针旋转 90 度(quarterTurns = 1)

quarterTurns: -1 逆时针旋转 90 度(quarterTurns = -1)。

代码实现文章来源地址https://www.toymoban.com/news/detail-806436.html

library flutter_timer_countdown;

import 'dart:async';
import 'package:LS/common/global.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';

enum CountDownTimerFormat {
  daysHoursMinutesSeconds,
  daysHoursMinutes,
  daysHours,
  daysOnly,
  hoursMinutesSeconds,
  hoursMinutes,
  hoursOnly,
  minutesSeconds,
  minutesOnly,
  secondsOnly,
}

typedef OnTickCallBack = void Function(Duration remainingTime);

class TimerCountdown extends StatefulWidget {
  /// Format for the timer coundtown, choose between different `CountDownTimerFormat`s
  final CountDownTimerFormat format;

  /// Defines the time when the timer is over.
  final DateTime endTime;

  /// Gives you remaining time after every tick.
  final OnTickCallBack? onTick;

  /// Function to call when the timer is over.
  final VoidCallback? onEnd;

  /// Toggle time units descriptions.
  final bool enableDescriptions;

  /// `TextStyle` for the time numbers.
  final TextStyle? timeTextStyle;

  /// `TextStyle` for the colons betwenn the time numbers.
  final TextStyle? colonsTextStyle;

  /// `TextStyle` for the description
  final TextStyle? descriptionTextStyle;

  /// Days unit description.
  final String daysDescription;

  /// Hours unit description.
  final String hoursDescription;

  /// Minutes unit description.
  final String minutesDescription;

  /// Seconds unit description.
  final String secondsDescription;

  /// Defines the width between the colons and the units.
  final double spacerWidth;

  final Widget? rightWidget;

  // 结束的 组件
  final Widget? endWidget;

  const TimerCountdown({
    required this.endTime,
    this.format = CountDownTimerFormat.daysHoursMinutesSeconds,
    this.enableDescriptions = true,
    this.onEnd,
    this.timeTextStyle,
    this.onTick,
    this.colonsTextStyle,
    this.descriptionTextStyle,
    this.daysDescription = "Days",
    this.hoursDescription = "Hours",
    this.minutesDescription = "Minutes",
    this.secondsDescription = "Seconds",
    this.spacerWidth = 10,
    this.rightWidget,
    this.endWidget,
  });

  @override
  _TimerCountdownState createState() => _TimerCountdownState();
}

class _TimerCountdownState extends State<TimerCountdown> {
  bool isEnd = false;
  Timer? timer;
  late String countdownDays;
  late String countdownHours;
  late String countdownMinutes;
  late String countdownSeconds;
  late Duration difference;

  @override
  void initState() {
    _startTimer();
    super.initState();
  }

  @override
  void dispose() {
    if (timer != null) {
      timer!.cancel();
    }
    super.dispose();
  }

  /// Calculate the time difference between now end the given [endTime] and initialize all UI timer values.
  ///
  /// Then create a periodic `Timer` which updates all fields every second depending on the time difference which is getting smaller.
  /// When this difference reached `Duration.zero` the `Timer` is stopped and the [onEnd] callback is invoked.
  void _startTimer() {
    if (widget.endTime.isBefore(Global.serverTime)) {
      difference = Duration.zero;
    } else {
      difference = widget.endTime.difference(Global.serverTime);
    }

    countdownDays = _durationToStringDays(difference);
    countdownHours = _durationToStringHours(difference);
    countdownMinutes = _durationToStringMinutes(difference);
    countdownSeconds = _durationToStringSeconds(difference);

    if (difference == Duration.zero) {
      if (widget.onEnd != null) {
        widget.onEnd!();
      }
      setState(() {
        isEnd = true;
      });
    } else {
      timer = Timer.periodic(const Duration(seconds: 1), (timer) {
        difference = widget.endTime.difference(Global.serverTime);
        widget.onTick?.call(difference);
        setState(() {
          countdownDays = _durationToStringDays(difference);
          countdownHours = _durationToStringHours(difference);
          countdownMinutes = _durationToStringMinutes(difference);
          countdownSeconds = _durationToStringSeconds(difference);
        });
        if (difference <= Duration.zero) {
          timer.cancel();
          if (widget.onEnd != null) {
            widget.onEnd!();
          }
          setState(() {
            isEnd = true;
          });
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Wrap(
      children: [
        if (widget.rightWidget != null && !isEnd) widget.rightWidget as Widget,
        _countDownTimerFormat(),
      ],
    );
  }

  /// Builds the UI colons between the time units.
  Widget _colon({String unit = ":"}) {
    return Row(
      children: [
        SizedBox(
          width: widget.spacerWidth,
        ),
        Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              unit.tr,
              style: widget.colonsTextStyle,
            ),
            if (widget.enableDescriptions)
              const SizedBox(
                height: 5,
              ),
            if (widget.enableDescriptions)
              Text(
                "",
                style: widget.descriptionTextStyle,
              ),
          ],
        ),
        SizedBox(
          width: widget.spacerWidth,
        ),
      ],
    );
  }

  /// Builds the timer days with its description.
  Widget _days(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(
          countdownDays.tr,
          style: widget.timeTextStyle,
        ),
        if (widget.enableDescriptions) const SizedBox(height: 5),
        if (widget.enableDescriptions)
          Text(
            widget.daysDescription.tr,
            style: widget.descriptionTextStyle,
          ),
      ],
    );
  }

  /// Builds the timer hours with its description.
  Widget _hours(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(
          countdownHours.tr,
          style: widget.timeTextStyle,
        ),
        if (widget.enableDescriptions) const SizedBox(height: 5),
        if (widget.enableDescriptions)
          Text(
            widget.hoursDescription.tr,
            style: widget.descriptionTextStyle,
          ),
      ],
    );
  }

  /// Builds the timer minutes with its description.
  Widget _minutes(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(
          countdownMinutes.tr,
          style: widget.timeTextStyle,
        ),
        if (widget.enableDescriptions) const SizedBox(height: 5),
        if (widget.enableDescriptions)
          Text(
            widget.minutesDescription.tr,
            style: widget.descriptionTextStyle,
          ),
      ],
    );
  }

  /// Builds the timer seconds with its description.
  Widget _seconds(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(
          countdownSeconds.tr,
          style: widget.timeTextStyle,
        ),
        if (widget.enableDescriptions) const SizedBox(height: 5),
        if (widget.enableDescriptions)
          Text(
            widget.secondsDescription.tr,
            style: widget.descriptionTextStyle,
          ),
      ],
    );
  }

  /// When the selected [CountDownTimerFormat] is leaving out the last unit, this function puts the UI value of the unit before up by one.
  ///
  /// This is done to show the currently running time unit.
  String _twoDigits(int n, String unitType) {
    switch (unitType) {
      case "minutes":
        if (widget.format == CountDownTimerFormat.daysHoursMinutes ||
            widget.format == CountDownTimerFormat.hoursMinutes ||
            widget.format == CountDownTimerFormat.minutesOnly) {
          if (difference > Duration.zero) {
            n++;
          }
        }
        if (n >= 10) return "$n";
        return "0$n";
      case "hours":
        if (widget.format == CountDownTimerFormat.daysHours ||
            widget.format == CountDownTimerFormat.hoursOnly) {
          if (difference > Duration.zero) {
            n++;
          }
        }
        if (n >= 10) return "$n";
        return "0$n";
      case "days":
        if (widget.format == CountDownTimerFormat.daysOnly) {
          if (difference > Duration.zero) {
            n++;
          }
        }
        if (n >= 10) return "$n";
        return "0$n";
      default:
        if (n >= 10) return "$n";
        return "0$n";
    }
  }

  /// Convert [Duration] in days to String for UI.
  String _durationToStringDays(Duration duration) {
    return _twoDigits(duration.inDays, "days").toString();
  }

  /// Convert [Duration] in hours to String for UI.
  String _durationToStringHours(Duration duration) {
    if (widget.format == CountDownTimerFormat.hoursMinutesSeconds ||
        widget.format == CountDownTimerFormat.hoursMinutes ||
        widget.format == CountDownTimerFormat.hoursOnly) {
      return _twoDigits(duration.inHours, "hours");
    } else
      return _twoDigits(duration.inHours.remainder(24), "hours").toString();
  }

  /// Convert [Duration] in minutes to String for UI.
  String _durationToStringMinutes(Duration duration) {
    if (widget.format == CountDownTimerFormat.minutesSeconds ||
        widget.format == CountDownTimerFormat.minutesOnly) {
      return _twoDigits(duration.inMinutes, "minutes");
    } else
      return _twoDigits(duration.inMinutes.remainder(60), "minutes");
  }

  /// Convert [Duration] in seconds to String for UI.
  String _durationToStringSeconds(Duration duration) {
    if (widget.format == CountDownTimerFormat.secondsOnly) {
      return _twoDigits(duration.inSeconds, "seconds");
    } else
      return _twoDigits(duration.inSeconds.remainder(60), "seconds");
  }

  /// Switches the UI to be displayed based on [CountDownTimerFormat].
  Widget _countDownTimerFormat() {
    if (isEnd) {
      return widget.endWidget == null
          ? Container()
          : widget.endWidget as Widget;
    }
    switch (widget.format) {
      case CountDownTimerFormat.daysHoursMinutesSeconds:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _days(context),
            _colon(unit: "天"),
            _hours(context),
            _colon(unit: ":"),
            _minutes(context),
            _colon(unit: ":"),
            _seconds(context),
            // Text(":".tr, style: widget.colonsTextStyle),
          ],
        );
      case CountDownTimerFormat.daysHoursMinutes:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _days(context),
            _colon(unit: "天"),
            _hours(context),
            _colon(unit: ":"),
            _minutes(context),
          ],
        );
      case CountDownTimerFormat.daysHours:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _days(context),
            _colon(unit: "天"),
            _hours(context),
          ],
        );
      case CountDownTimerFormat.daysOnly:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _days(context),
          ],
        );
      case CountDownTimerFormat.hoursMinutesSeconds:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _hours(context),
            _colon(unit: ":"),
            _minutes(context),
            _colon(unit: ":"),
            _seconds(context),
            // Text(":".tr, style: widget.colonsTextStyle),
          ],
        );
      case CountDownTimerFormat.hoursMinutes:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _hours(context),
            _colon(unit: ":"),
            _minutes(context),
          ],
        );
      case CountDownTimerFormat.hoursOnly:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _hours(context),
          ],
        );
      case CountDownTimerFormat.minutesSeconds:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _minutes(context),
            _colon(unit: ":"),
            _seconds(context),
          ],
        );

      case CountDownTimerFormat.minutesOnly:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _minutes(context),
          ],
        );
      case CountDownTimerFormat.secondsOnly:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _seconds(context),
          ],
        );
      default:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _days(context),
            _colon(unit: "天"),
            _hours(context),
            _colon(unit: ":"),
            _minutes(context),
            _colon(unit: ":"),
            _seconds(context),
          ],
        );
    }
  }
}

到了这里,关于flutter 实现时间流失效果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaScript实现放大镜效果

    问题描述:利用JavaScript知识实现鼠标在左侧照片上移动,右侧盒子内出现放大版的对应位置效果图。 详细代码: 效果图:  

    2024年03月11日
    浏览(33)
  • flutter开发实战-实现自定义按钮类似UIButton效果

    flutter开发实战-实现自定义按钮类似UIButton效果 最近开发过程中需要实现一下UIButton效果的flutter按钮,这里使用的是监听手势点击事件。 GestureDetector属性定义 由于属性太多,我们实现onTapDown、onTapUp、onTapCancel、onTap。 实现自定义按钮类似,我们实现onTapDown、onTapUp、onTapCance

    2024年02月14日
    浏览(34)
  • flutter web项目中鼠标拖动无法实现滚动效果

    在完成web的flutter项目时,发现ListView列表使用鼠标拖动无法滚动,尝试发现使用触摸板可以实现滚动,但如果用户使用没有触摸板的电脑或列表为横向滚动时就无法实现项目需求了,在解决问题的过程中尝试了以下方法: 1.尝试使用点击事件模拟滑动手势 如果web项目中无法使

    2024年02月09日
    浏览(31)
  • flutter开发实战-flutter实现类似iOS的Alert提示框与sheet菜单效果

    flutter开发实战-flutter实现类似iOS的Alert提示框与sheet菜单效果 在开发过程中,经常使用到提示框Dialog,与sheet,使用到了flutter的showDialog与showModalBottomSheet 我这里类似alert弹窗直接调用 flutter 中提供的showDialog()函数显示对话框。 我这里类似Sheet底部弹窗调用 flutter 中提供的show

    2024年02月16日
    浏览(27)
  • 使用JavaScript实现页面滑动切换效果

      使用JavaScript实现页面滑动切换效果 在现代Web页面设计中,页面滑动切换效果已经成为了一种常见的设计要求,能够提升用户体验,增加页面的交互性。本文将通过JavaScript来实现这一效果。 首先,我们需要在HTML中添加一些基础结构和样式。以下是一个简单的例子:   在

    2024年02月13日
    浏览(40)
  • flutter开发实战-实现左右来回移动的按钮引导动画效果

    flutter开发实战-实现左右来回移动的按钮引导动画效果 最近开发过程中需要实现左右来回移动的按钮引导动画效果 AnimationController用来控制一个或者多个动画的正向、反向、停止等相关动画操作。在默认情况下AnimationController是按照线性进行动画播放的。AnimationController两个监听

    2024年02月13日
    浏览(33)
  • flutter开发实战-inappwebview实现flutter与Javascript的交互JSBridge

    flutter开发实战-inappwebview实现flutter与Javascript的交互JSBridge 在使用webview中,需要实现flutter与Javascript交互,在使用webview_flutter插件的时候,整理了一下webview与Javascript的交互JSBridge,具体可以查看 https://blog.csdn.net/gloryFlow/article/details/131683122 这里使用inappwebview插件来实现flutter与

    2024年02月08日
    浏览(34)
  • Flutter实现PS钢笔工具,实现高精度抠图的效果。

    演示:  代码: stack代码: 主要思路: 更具手指点击屏幕的位置,记录点击的位置,并生成绘制点和两个控制点,手指拖动控制点时,动态刷新控制点位置,然后利用flutter绘制机制,在canvas上根据点的位置和控制点的位置绘制三阶贝塞尔曲线,实现钢笔工具效果。具体实现

    2024年02月07日
    浏览(32)
  • JavaScript实现液体流动效果和鼠标交互

    在现代Web应用中,动态效果和交互性已经成为了不可或缺的元素。在这篇博客中,我们将使用JavaScript创建一个液体流动效果,并添加鼠标交互功能,让用户能够与页面进行互动。 创建画布和粒子 首先,我们需要创建一个画布元素,用于绘制我们的液体流动效果。在HTML中添加

    2024年02月13日
    浏览(40)
  • JavaScript实现背景图像切换3D动画效果

    🐱 个人主页: 不叫猫先生 🙋‍♂️ 作者简介:2022年度博客之星前端领域TOP 2,前端领域优质作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀! 💫优质专栏:vue3从入门到精通、TypeScript从入门到实践 📢 资料领取:前端进阶资料以及文中源

    2023年04月20日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包