flutter - 如何在flutter中实现这样的过渡效果?
问题描述
我尝试了 Hero 小部件和页面路由来在像这个gif这样的页面之间切换 。
我曾尝试使用自定义页面路由,使用 Stack 小部件包装两个页面,并在 buildTransitions 中进行动画处理,但很难计算比例对齐,并且英雄小部件没有从前一页中删除。
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)),
]);
}
}
有没有其他思路可以提供?</p>
解决方案
尝试动画,容器变换:
_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,
);
}
}
推荐阅读
- google-chrome - 如何防止 Chrome 扩展在浏览器重启时重置选项?
- android - 为检测到的人脸添加过滤器
- python - 在 keras 中加载测试图像
- python - 获取/过滤与 Python 中的属性/键匹配的对象列表中的第一项
- r - 是否可以在 r 中将 OCHA 图标添加到传单地图?
- angular - 错误类型错误:无法读取未定义角度服务的属性“isSupported”:ssr
- python - 如何从 Flask Python 应用程序向 Discord 机器人发出带有 JSON 的 POST 请求
- c++ - 通过加载二进制数据而不是文本和转换来提高代码性能
- python - AWS Glue python shell - 使用多个库
- asp.net - DevExpress WebDocumentViewer - 如何根据条件禁用打印按钮