Flutter开发倒计时按钮CountDownButton,可绝对时间计时,关闭界面不影响计时。

  • 演示

 点击后开始倒计时,推出当前界面,计时依然会继续,不会导致内存泄漏,实现原理是保存第一次开始计时的当前时间到本地,当再次进入时,取出退出时保存的值,然后跟当前值对比,得出差值,然后再跟计时时间相减,得出已倒计时耗费时间,然后减去该耗费时间,根据剩余时间继续计时。

 

  • 功能

1.可设置倒计时值。

2.点击会回调state,可手动开始计时器。

3.可保存绝对时间,不间断计时。

4.可设置计时完成后显示值。

  • 代码
import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:xzg_pda_flutter/components/button/kq_small_button.dart';

import '../../config/global.dart';
import '../../resources/l10n/l10n.dart';

class CountDownButton extends StatefulWidget {
  /// 倒计时数值
  final int countDownValue;

  /// session值,保持界面绝对倒计时
  final String session;

  /// 非计时时显示的按钮文字
  final String? text;

  /// 点击后的回调
  final Function(CountDownButtonState state)? onTap;

  const CountDownButton({
    super.key,
    required this.countDownValue,
    required this.session,
    this.text,
    this.onTap,
  });

  @override
  State<StatefulWidget> createState() => CountDownButtonState();
}

class CountDownButtonState extends State<CountDownButton> {
  final String boolSuffix = "BOOL";
  final String intSuffix = "INT";

  /// 当前进度文本
  late String _text;

  /// 按钮是否不可用
  bool _disabled = false;

  /// 计时器
  Timer? timer;

  /// 开始计时时的时间戳
  int? _startTimeMillis;

  /// 是否是计时状态
  bool? _isStart;

  @override
  void initState() {
    super.initState();
    _text = widget.text ?? S.of(context).confirm;
    _isStart = Global.prefs?.getBool(widget.session + boolSuffix) ?? false;
    int currentTimeMillis = DateTime.now().millisecondsSinceEpoch;
    int startTimeMillis = Global.prefs?.getInt(widget.session + intSuffix) ?? 0;
    if (startTimeMillis != 0 &&
        (currentTimeMillis - startTimeMillis) / 1000 <= widget.countDownValue &&
        (_isStart ?? false)) {
      startTimer();
    }
  }

  void startTimer() {
    int count = 0;
    int currentTimeMillis = DateTime.now().millisecondsSinceEpoch;
    int startTimeMillis = Global.prefs?.getInt(widget.session + intSuffix) ?? 0;
    if (startTimeMillis == 0 ||
        (currentTimeMillis - startTimeMillis) / 1000 > widget.countDownValue) {
      _startTimeMillis = currentTimeMillis;
    } else {
      count = (currentTimeMillis - startTimeMillis) ~/ 1000;
      _startTimeMillis = startTimeMillis;
    }
    //计时器,每1秒执行一次
    const period = Duration(seconds: 1);
    timer = Timer.periodic(period, (timer) {
      count++;
      num max = widget.countDownValue;
      //计时器结束条件
      if (widget.countDownValue == 0 || count >= max) {
        timer.cancel();
        if (mounted) {
          _isStart = false;
          Global.prefs?.setBool(widget.session + boolSuffix, false);
          Global.prefs?.setInt(widget.session + intSuffix, 0);
          setState(() {
            _text = widget.text ?? S.of(context).confirm;
            _disabled = false;
          });
        }
      } else {
        if (mounted) {
          _isStart = true;
          setState(() {
            _text = (widget.countDownValue - count).toString();
            _disabled = true;
          });
        }
      }
    });
  }

  @override
  void dispose() {
    //退出时关闭计时器防止内存泄露
    timer?.cancel();
    Global.prefs?.setBool(widget.session + boolSuffix, _isStart ?? false);
    Global.prefs?.setInt(widget.session + intSuffix, _startTimeMillis ?? 0);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return KqSmallButton(
      disabled: _disabled,
      title: _text,
      onTap: (disabled) {
        if (widget.onTap != null && !disabled) {
          widget.onTap!(this);
        }
      },
    );
  }
}
  • 使用
CountDownButton(
    countDownValue: 30,
    session: "login_view",
    text: "点我测试",
    onTap: (state) {
        state.startTimer();
    },
)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Flutter 中实现验证码倒计时可以通过使用计时器 Timer 来实现。以下是一个简单的示例: 1. 首先定义一个变量 `countdownTime` 表示倒计时时间,以秒为单位。 ```dart int countdownTime = 60; ``` 2. 然后定义一个变量 `timer` 来控制计时器的执行。 ```dart Timer timer; ``` 3. 在需要开始倒计时的时候,启动计时器,并在计时器中更新倒计时时间。 ```dart void startCountdown() { timer = Timer.periodic(Duration(seconds: 1), (timer) { setState(() { if (countdownTime < 1) { timer.cancel(); } else { countdownTime -= 1; } }); }); } ``` 4. 在界面中显示倒计时时间。可以使用 Text 组件来显示,然后在组件的 text 属性中使用字符串插值来显示倒计时时间。 ```dart Text('倒计时 $countdownTime 秒') ``` 完整的示例代码如下: ```dart import 'dart:async'; import 'package:flutter/material.dart'; class CountdownPage extends StatefulWidget { @override _CountdownPageState createState() => _CountdownPageState(); } class _CountdownPageState extends State<CountdownPage> { int countdownTime = 60; Timer timer; void startCountdown() { timer = Timer.periodic(Duration(seconds: 1), (timer) { setState(() { if (countdownTime < 1) { timer.cancel(); } else { countdownTime -= 1; } }); }); } @override void dispose() { timer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('验证码倒计时'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('倒计时 $countdownTime 秒'), SizedBox(height: 16), RaisedButton( child: Text('开始倒计时'), onPressed: startCountdown, ), ], ), ), ); } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许天成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值