Flutter 倒计时计时器

135

我该怎么做才能将传递给构造函数的值用于创建一个四舍五入到小数点后一位的定时器,并显示在RaisedButton子文本中?我尝试过,但没有成功。我设法使用简单的Timer使回调函数运行,但没有周期性,并且文本中的值无法实时更新...

import 'package:flutter/material.dart';
import 'dart:ui';
import 'dart:async';

class TimerButton extends StatefulWidget {
  final Duration timerTastoPremuto;


  TimerButton(this.timerTastoPremuto);

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

class _TimerButtonState extends State<TimerButton> {
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.all(5.0),
      height: 135.0,
      width: 135.0,
      child: new RaisedButton(
        elevation: 100.0,
        color: Colors.white.withOpacity(.8),
        highlightElevation: 0.0,
        onPressed: () {
          int _start = widget.timerTastoPremuto.inMilliseconds;

          const oneDecimal = const Duration(milliseconds: 100);
          Timer _timer = new Timer.periodic(
              oneDecimal,
                  (Timer timer) =>
                  setState(() {
                    if (_start < 100) {
                      _timer.cancel();
                    } else {
                      _start = _start - 100;
                    }
                  }));

        },
        splashColor: Colors.red,
        highlightColor: Colors.red,
        //shape: RoundedRectangleBorder e tutto il resto uguale
        shape: BeveledRectangleBorder(
            side: BorderSide(color: Colors.black, width: 2.5),
            borderRadius: new BorderRadius.circular(15.0)),
        child: new Text(
          "$_start",
          style: new TextStyle(fontFamily: "Minim", fontSize: 50.0),
        ),
      ),
    );
  }
}

请添加一些代码,您的问题不够清晰。 - satish
1
是的,只需使用 setState 来更新值,不要在其中放置任何小部件。 - Yann39
计时器的代码是什么?你能给我提供一个链接吗? - Floris Marpepa
使用 Timer 类来表示一个可以使用 Timer.periodic 重复触发的计时器。您还可以查看 Stopwatch 类。 - Yann39
14个回答

1
许多答案已经提供。我建议一种快捷方式-使用此包Custom_timer将其添加到您的包的pubspec.yaml文件中:
dependencies:
  custom_timer: ^0.0.3 

(使用最新版本)
并且非常简单易于实现。
@override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text("CustomTimer example"),
        ),
        body: Center(
          child: CustomTimer(
            from: Duration(hours: 12),
            to: Duration(hours: 0),
            onBuildAction: CustomTimerAction.auto_start,
            builder: (CustomTimerRemainingTime remaining) {
              return Text(
                "${remaining.hours}:${remaining.minutes}:${remaining.seconds}",
                style: TextStyle(fontSize: 30.0),
              );
            },
          ),
        ),
      ),
    );
  }

谢谢Abir,这个包能否从零开始计数而不是倒计时?当按下按钮并导航到其他页面时,如何保存经过的时间(计时)? - VegetaSaiyan

0
import 'package:async/async.dart';
    
late CancelableOperation? cancellableOperation;
int counter = 5;

StatefulBuilder(
   builder: (context, setState) {
              if (counter > 0) {
                cancellableOperation = CancelableOperation.fromFuture(
                  Future.delayed(const Duration(seconds: 1)),
                  onCancel: () => {},
                );
                cancellableOperation?.value.whenComplete(() => setState(() => counter--));
                return buildButton(
                  text: 'Wait($counter)',
                  textColor: getTextColor,
                  backgroundColor: Colors.grey.withOpacity(0.5),
                  onPressed: () {},
                );
              }
              return buildButton(
                text: 'Complete',
                textColor: Colors.green,
                backgroundColor: Colors.greenAccent.withOpacity(0.5),
                onPressed: () {},
              );
            },
          )

我为我的对话框的完成按钮做了类似的事情。它在显示完成按钮之前计数5秒钟。但是,在计数完成之前,不要忘记调用cancellableOperation?.cancel(),如果你在计数完成之前关闭了对话框或页面。


0
import 'package:rxdart/rxdart.dart';

final BehaviorSubject<int> resendTimeController = BehaviorSubject<int>();
static const timerDuration = 90;
int resendTimer = 0;
Timer? timer;

void startTimer() {
  timer?.cancel();
  resendTimer = timerDuration;

  timer = Timer.periodic(const Duration(seconds: 1), (timer) {
    if (resendTimer > 0) {
      resendTimer--;
      resendTimeController.add(resendTimer);

      if (resendTimer == 0) {
        timer.cancel();
      }
    }
  });
}
and use intl this

StreamBuilder<int>(
  stream: _bloc.resendTimeController,
  builder: (context, snapshot) {
    if (!snapshot.hasData) {
      return Container();
    }

    final DateTime date = DateTime.fromMillisecondsSinceEpoch(snapshot.data! * 1000);

    return GestureDetector(
      onTap: () {
        if (snapshot.data == 0) {
          _bloc.resendCode();
        }
      },
      child: Text(
        snapshot.data! > 0 ? 'Resend code ${DateFormat('mm:ss').format(date)}' : 'Resend SMS',
      ),
    );
  },
),

1
目前您的回答不太清晰。请进行[编辑],添加更多细节以帮助其他人理解如何回答所问的问题。您可以在帮助中心中找到有关如何撰写好的答案的更多信息。 - Community

-3

一行代码实现倒计时

CountdownTimer(Duration(seconds: 5), Duration(seconds: 1)).listen((data){
})..onData((data){
  print('data $data');
})..onDone((){
  print('onDone.........');
});

13
CountdownTimer是第三方库中的一个类吗?请包含该库的包。 - Yudi karma
请添加更多的解释。 - Teodoro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接