更改选项卡时继续计时器

问题描述 投票:-1回答:1

我有一个基于时间的应用程序,其中我在一个选项卡上显示计时器(倒计时)和下一个选项卡上的一些文章。

现在,用户可以自由阅读文章,直到计时器正在滴答作响。但是当用户更改选项卡时,计时器会重置。

当状态改变时,我不重建计时器。它被放置为静态变量并且只初始化一次。

任何帮助,将不胜感激。

到目前为止我所做的总结:

1)创建一个静态变量static var timer = CountdownTimer()

2)用它来创建一个listtile。 ListTile(...,尾随:Classname.timer)

3)启动计时器。定时器工作正常。

4)更改了页面。可以看到计时器仍在运行(通过放置在ProgressPainter中的print语句)。

5)计时器没有变化。

class CountdownTimer extends StatefulWidget{
  var timer = CountdownTimerState();

  @override
  State<StatefulWidget> createState() {
    timer = CountdownTimerState();
//  timer._controller.duration =
    return timer;
  }
}

class CountdownTimerState extends State<CountdownTimer> with TickerProviderStateMixin{
  AnimationController _controller;

  String get timeRemaining{
    Duration duration = _controller.duration * _controller.value;
    return '${duration.inMinutes} : ${(duration.inSeconds % 60).toString().padLeft(2,'0')}';
  }


  startTimer(){
    print('called');
    _controller.reverse(from: 1);
  }

  stopTimer(){
    _controller.reverse(from: 0);
  }
  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this,duration: const Duration(seconds: 180));
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 60,
      height: 60,
      child: Align(alignment: FractionalOffset.center,child: AspectRatio(aspectRatio: 1.0,child: Stack(
        children: <Widget>[
          Positioned.fill(child: AnimatedBuilder(animation: _controller, builder: (BuildContext context,Widget child){
            return CustomPaint(
              painter: ProgressPainter(animation: _controller, backgroundColor: Colors.purple, color: Colors.white54),
            );
          })),
          Align(
            alignment: FractionalOffset.center,
            child: AnimatedBuilder(animation: _controller, builder: (BuildContext context,Widget child){
              return Text(timeRemaining,style: TextStyle(fontSize: 20,fontWeight: FontWeight.w400,color: Colors.white),);
            })
          )
        ],
      ),),),
    );
  }
}


class ProgressPainter extends CustomPainter {
  ProgressPainter({
    @required this.animation,
    @required this.backgroundColor,
    @required this.color,
  }) : super(repaint: animation);

  /// Animation representing what we are painting
  final Animation<double> animation;

  /// The color in the background of the circle
  final Color backgroundColor;

  /// The foreground color used to indicate progress
  final Color color;

  @override
  void paint(Canvas canvas, Size size) {
    print('Timer is running');
    Paint paint = new Paint()
      ..color = backgroundColor
      ..strokeWidth = 1.0
      ..strokeCap = StrokeCap.butt
      ..style = PaintingStyle.fill;
    canvas.drawCircle(size.center(Offset.zero), size.width / 2.0, paint);
    paint.color = color;
    double progressRadians = (1.0 - animation.value) * 2 * math.pi;
    canvas.drawArc(
        Offset.zero & size, math.pi * 1.5, -progressRadians, false, paint);
  }

  @override
  bool shouldRepaint(ProgressPainter other) {
    return animation.value != other.animation.value ||
        color != other.color ||
        backgroundColor != other.backgroundColor;
  }
}
dart flutter
1个回答
0
投票

创建一个timer_bloc.dart文件并在其中包含以下Bloc:

final timerBloc = TimerBloc();

class TimerBloc {
  Timer _timer;

  int _start = 10;

  StreamController<int> timerStreamController = StreamController<int>.broadcast();

  Stream get timerStream {
    if(!timerStreamController.hasListener){
      startTimer();
    }
    return timerStreamController.stream;
  }


  void startTimer() {
    const oneSec = const Duration(seconds: 1);
    _timer = new Timer.periodic(oneSec, (Timer timer) {
      if (_start < 1) {
        timer.cancel();
      } else {
        _start = _start - 1;
      }
      timerStreamController.sink.add(_start);
    });
  }

  stopTimer() {
    _timer?.cancel();
  }

  dispose() {
    timerStreamController.close();
  }
}

现在,只要你的应用程序计时器滴答更新,只需使用像这样的StreamBuilder小部件。

return StreamBuilder(
  stream: timerBloc.timerStream,
  builder: (context, snapshot) {
  return Text(snapshot.data.toString());
},);
© www.soinside.com 2019 - 2024. All rights reserved.