Reputation: 53
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?
Upvotes: 1
Views: 648
Reputation: 7601
try animations, Container transform:
_OpenContainerWrapper(
transitionType: _transitionType,
closedBuilder: (BuildContext _, VoidCallback openContainer) {
return _ExampleCard(openContainer: openContainer);
},
onClosed: _showMarkedAsDoneSnackbar,
),
class _OpenContainerWrapper extends StatelessWidget {
const _OpenContainerWrapper({
required this.closedBuilder,
required this.transitionType,
required this.onClosed,
});
final CloseContainerBuilder closedBuilder;
final ContainerTransitionType transitionType;
final ClosedCallback<bool?> onClosed;
@override
Widget build(BuildContext context) {
return OpenContainer<bool>(
transitionType: transitionType,
openBuilder: (BuildContext context, VoidCallback _) {
return const _DetailsPage();
},
onClosed: onClosed,
tappable: false,
closedBuilder: closedBuilder,
);
}
}
Upvotes: 1