| 1 | import 'package:flutter/material.dart'; |
| 2 | |
| 3 | class DirectionalAnimatedSwitcher extends StatefulWidget { |
| 4 | final Widget child; |
| 5 | final Duration duration; |
| 6 | |
| 7 | const DirectionalAnimatedSwitcher({ |
| 8 | super.key, |
| 9 | required this.child, |
| 10 | required this.duration, |
| 11 | }); |
| 12 | |
| 13 | @override |
| 14 | State<DirectionalAnimatedSwitcher> createState() => _DirectionalAnimatedSwitcherState(); |
| 15 | } |
| 16 | |
| 17 | class _DirectionalAnimatedSwitcherState extends State<DirectionalAnimatedSwitcher> { |
| 18 | bool _isForward = true; |
| 19 | |
| 20 | @override |
| 21 | void didUpdateWidget(DirectionalAnimatedSwitcher oldWidget) { |
| 22 | super.didUpdateWidget(oldWidget); |
| 23 | |
| 24 | final oldKey = (oldWidget.child.key as ValueKey<int>).value; |
| 25 | final newKey = (widget.child.key as ValueKey<int>).value; |
| 26 | |
| 27 | if (newKey != oldKey) { |
| 28 | _isForward = newKey > oldKey; |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | @override |
| 33 | Widget build(BuildContext context) { |
| 34 | return AnimatedSwitcher( |
| 35 | duration: widget.duration, |
| 36 | transitionBuilder: (Widget child, Animation<double> animation) { |
| 37 | final double offset = _isForward ? 1.2 : -1.2; |
| 38 | |
| 39 | final inTween = Tween(begin: Offset(offset, 0.0), end: Offset.zero) |
| 40 | .chain(CurveTween(curve: Curves.easeInOutCubic)); |
| 41 | |
| 42 | final outTween = Tween(begin: Offset(-offset, 0.0), end: Offset.zero) |
| 43 | .chain(CurveTween(curve: Curves.easeInOutCubic)); |
| 44 | |
| 45 | if (child.key == widget.child.key) { |
| 46 | return SlideTransition(position: animation.drive(inTween), child: child); |
| 47 | } else { |
| 48 | return SlideTransition(position: animation.drive(outTween), child: child); |
| 49 | } |
| 50 | }, |
| 51 | child: widget.child, |
| 52 | ); |
| 53 | } |
| 54 | } |