更改标签后继续计时

时间:2019-04-13 16:25:25

标签: dart flutter

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

现在,用户可以自由阅读文章,直到计时器计时为止。 但是,当用户更改标签时,计时器会重置。

状态更改时,我不重建计时器。它作为静态变量放置,仅初始化一次。

任何帮助将不胜感激。

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

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

2)使用它来创建列表对象。 ListTile(...,trailing:Classname.timer)

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

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

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;
  }
}

1 个答案:

答案 0 :(得分: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 Widget即可。

return StreamBuilder(
  stream: timerBloc.timerStream,
  builder: (context, snapshot) {
  return Text(snapshot.data.toString());
},);