我有一个基于时间的应用程序,其中我在一个选项卡上显示计时器(倒数),在下一个选项卡上显示一些文章。
现在,用户可以自由阅读文章,直到计时器计时为止。 但是,当用户更改标签时,计时器会重置。
状态更改时,我不重建计时器。它作为静态变量放置,仅初始化一次。
任何帮助将不胜感激。
到目前为止我所做的总结:
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;
}
}
答案 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());
},);