I tried Hero widget and page route to switch between pages like this gif.
I had try with custom page route, use Stack widget to wrap two pages, and animated in buildTransitions, but it is hard to calculate scale alignment and hero widget didn't remove from the previous page.
class CustomPageRoute extends MaterialPageRoute {
final Widget parentWidget;
final Alignment parentAlignment;
final Tween<double> childScaleTween;
final double childWidth;
CustomPageRoute(
{required this.parentWidget,
required this.parentAlignment,
required this.childScaleTween,
required this.childWidth,
required WidgetBuilder builder,
RouteSettings? settings})
: super(builder: builder, settings: settings);
@override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return builder(context);
}
@override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
Curve animatedCurves = Curves.linear;
var scale = MediaQuery.of(context).size.width / childWidth;
var scaleAnim = Tween(begin: 1.0, end: scale)
.animate(CurvedAnimation(parent: animation, curve: animatedCurves));
var fadeAnim = Tween(begin: 1.0, end: 0.0)
.animate(CurvedAnimation(parent: animation, curve: animatedCurves));
var childScaleAnim = childScaleTween
.animate(CurvedAnimation(parent: animation, curve: animatedCurves));
var childFadeAnim = Tween(begin: 0.0, end: 1.0)
.animate(CurvedAnimation(parent: animation, curve: animatedCurves));
return Stack(children: [
Container(
color: Colors.white,
),
ScaleTransition(
scale: scaleAnim,
alignment: parentAlignment,
child: FadeTransition(opacity: fadeAnim, child: parentWidget)),
ScaleTransition(
scale: childScaleAnim,
alignment: parentAlignment,
child: FadeTransition(opacity: childFadeAnim, child: child)),
]);
}
}
Are there any other ideas to provide?