import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:info_tren/train_info_page/train_info_constants.dart'; import 'dart:io' show Platform; class AnimatedBackground extends StatefulWidget { final Color initialColor; final Color backgroundColor; final Widget child; final Duration animationDuration; AnimatedBackground({Key key, @required this.initialColor, @required this.backgroundColor, Duration animationDuration, @required this.child}) : this.animationDuration = animationDuration ?? Duration(milliseconds: 250) , super(key: key); @override State createState() => _AnimatedBackgroundState(); } class _AnimatedBackgroundState extends State with SingleTickerProviderStateMixin { AnimationController controller; Animatable animation; @override void initState() { super.initState(); controller = AnimationController(vsync: this, duration: widget.animationDuration); controller.forward(); animation = ColorTween(begin: widget.initialColor, end: widget.backgroundColor); } @override void didUpdateWidget(AnimatedBackground oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.backgroundColor != widget.backgroundColor) { controller = AnimationController( duration: widget.animationDuration, vsync: this ); controller.forward(); animation = ColorTween( begin: oldWidget.backgroundColor, end: widget.backgroundColor ); } } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: controller, child: widget.child, builder: (context, child) { return Container( decoration: BoxDecoration( color: animation.evaluate(controller), ), child: child, ); }, ); } } class ProgressReportDisplayEntry extends StatefulWidget { final bool completed; final String waitingText; final String completedText; String get text => completed ? completedText : waitingText; ProgressReportDisplayEntry({Key key, @required this.completed, @required this.waitingText, @required this.completedText}): super(key: key); @override State createState() { if (Platform.isIOS) { return _ProgressReportDisplayEntryCupertinoState(); } else if (Platform.isAndroid) { return _ProgressReportDisplayEntryMaterialState(); } else return null; } } class _ProgressReportDisplayEntryCupertinoState extends State with SingleTickerProviderStateMixin { Animatable background; Animatable checkMark; AnimationController _controller; initAnimation() { background = ColorTween( begin: CupertinoTheme.of(context).scaffoldBackgroundColor, end: BACKGROUND_GREEN, ); checkMark = ColorTween( begin: FOREGROUND_WHITE, end: FOREGROUND_GREEN, ); } @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 250), vsync: this, ); _controller.value = widget.completed ? 1 : 0; } @override void didChangeDependencies() { super.didChangeDependencies(); initAnimation(); } @override void didUpdateWidget(ProgressReportDisplayEntry oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.completed != widget.completed) { if (widget.completed) { _controller.forward(); } else { _controller.reverse(); } } } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, _) { return Container( decoration: BoxDecoration( color: background.evaluate(_controller) ), child: Row( children: [ Center( child: Padding( padding: const EdgeInsets.all(4), child: Container( width: 32, height: 32, child: !widget.completed ? CupertinoActivityIndicator() : Icon(CupertinoIcons.check_mark_circled, color: checkMark.evaluate(_controller)), ), ), ), Expanded( child: Padding( padding: const EdgeInsets.all(4), child: Text(widget.text), ), ) ], ), ); } ); } } class _ProgressReportDisplayEntryMaterialState extends State with SingleTickerProviderStateMixin { Animatable background; Animatable checkMark; AnimationController _controller; initAnimation() { background = ColorTween( begin: Theme.of(context).scaffoldBackgroundColor, end: Colors.green, ); checkMark = ColorTween( begin: Colors.white, end: Colors.greenAccent, ); } @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 250), vsync: this, ); _controller.value = widget.completed ? 1 : 0; } @override void didChangeDependencies() { super.didChangeDependencies(); initAnimation(); } @override void didUpdateWidget(ProgressReportDisplayEntry oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.completed != widget.completed) { if (widget.completed) { _controller.forward(); } else { _controller.reverse(); } } } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, _) { return Container( decoration: BoxDecoration( color: background.evaluate(_controller) ), child: Row( children: [ Center( child: Padding( padding: const EdgeInsets.all(4), child: Container( width: 32, height: 32, child: !widget.completed ? CircularProgressIndicator(strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.orangeAccent),) : Icon(Icons.check_circle, color: checkMark.evaluate(_controller), size: 32,), ), ), ), Expanded( child: Padding( padding: const EdgeInsets.all(4), child: Text(widget.text), ), ) ], ), ); } ); } }