254 lines
6.8 KiB
Dart
254 lines
6.8 KiB
Dart
|
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<AnimatedBackground> createState() => _AnimatedBackgroundState();
|
||
|
}
|
||
|
|
||
|
class _AnimatedBackgroundState extends State<AnimatedBackground> with SingleTickerProviderStateMixin {
|
||
|
AnimationController controller;
|
||
|
Animatable<Color> 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<ProgressReportDisplayEntry> createState() {
|
||
|
if (Platform.isIOS) {
|
||
|
return _ProgressReportDisplayEntryCupertinoState();
|
||
|
}
|
||
|
else if (Platform.isAndroid) {
|
||
|
return _ProgressReportDisplayEntryMaterialState();
|
||
|
}
|
||
|
else return null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class _ProgressReportDisplayEntryCupertinoState extends State<ProgressReportDisplayEntry> with SingleTickerProviderStateMixin {
|
||
|
Animatable<Color> background;
|
||
|
Animatable<Color> 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: <Widget>[
|
||
|
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<ProgressReportDisplayEntry> with SingleTickerProviderStateMixin {
|
||
|
Animatable<Color> background;
|
||
|
Animatable<Color> 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: <Widget>[
|
||
|
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),
|
||
|
),
|
||
|
)
|
||
|
],
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
}
|