workouttest_app/lib/library/fade_in.dart
2021-04-02 11:42:26 +02:00

139 lines
2.9 KiB
Dart

import 'dart:async';
import 'package:flutter/widgets.dart';
class FadeIn extends StatefulWidget {
/// Fade-in controller
final FadeInController controller;
/// Child widget to fade-in
final Widget child;
/// Duration of fade-in. Defaults to 250ms
final Duration duration;
/// Fade-in curve. Defaults to [Curves.easeIn]
final Curve curve;
const FadeIn({
Key? key,
required this.controller,
required this.child,
this.duration = const Duration(milliseconds: 250),
this.curve = Curves.easeIn,
}) : super(key: key);
@override
_FadeInState createState() => _FadeInState();
}
enum FadeInAction {
fadeIn,
fadeOut,
}
/// Fade-in controller which dispatches fade-in/fade-out actions
class FadeInController {
final _streamController = StreamController<FadeInAction>();
/// Automatically starts the initial fade-in. Defaults to true
final bool autoStart;
FadeInController({this.autoStart = true});
void dispose() => _streamController.close();
/// Fades-in child
void fadeIn() => run(FadeInAction.fadeIn);
/// Fades-out child
void fadeOut() => run(FadeInAction.fadeOut);
/// Dispatches a [FadeInAction]
void run(FadeInAction action) => _streamController.add(action);
/// Stream of [FadeInAction]s dispatched by this controller
Stream<FadeInAction> get stream => _streamController.stream;
}
class _FadeInState extends State<FadeIn> with TickerProviderStateMixin {
late AnimationController _controller;
late StreamSubscription<FadeInAction> _listener;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: widget.duration,
);
_setupCurve();
if (widget.controller.autoStart != false) {
fadeIn();
}
_listener = widget.controller.stream.listen(_onAction);
}
void _setupCurve() {
final curve = CurvedAnimation(parent: _controller, curve: widget.curve);
Tween(
begin: 0.0,
end: 1.0,
).animate(curve);
}
void _onAction(FadeInAction action) {
switch (action) {
case FadeInAction.fadeIn:
fadeIn();
break;
case FadeInAction.fadeOut:
fadeOut();
break;
}
}
@override
void didUpdateWidget(FadeIn oldWidget) {
if (oldWidget.controller != widget.controller) {
_listener = widget.controller.stream.listen(_onAction);
}
if (oldWidget.duration != widget.duration) {
_controller.duration = widget.duration;
}
if (oldWidget.curve != widget.curve) {
_setupCurve();
}
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
_controller.dispose();
_listener.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _controller,
child: widget.child,
);
}
/// Fades-in child
void fadeIn() => _controller.forward();
/// Fades-out child
void fadeOut() => _controller.reverse();
}