可以使用 Flutter 复制 iOS App Store 过渡吗?
Posted
技术标签:
【中文标题】可以使用 Flutter 复制 iOS App Store 过渡吗?【英文标题】:Possible to copy iOS App Store transition using Flutter? 【发布时间】:2020-10-15 21:29:32 【问题描述】:是否可以使用 Flutter 复制 ios App Store 的过渡效果?
我尝试通过在两个小部件的根布局中放置两个标签来使用 Hero Animation,但动画看起来很卡,或者不是我预期的那样。但这样做的好处是我能够在使用 MaterialPageRoute 时将 iOS 向后滑动。
来源
Hero(
tag: 'heroTag_destinationScreen',
transitionOnUserGestures: true,
flightShuttleBuilder: (BuildContext flightContext,
Animation<double> animation,
HeroFlightDirection flightDirection,
BuildContext fromHeroContext,
BuildContext toHeroContext,)
final Hero toHero = toHeroContext.widget;
return ScaleTransition(
scale: animation,
child: toHero,
);
,
child: GestureDetector(
onTap: ()
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context)
return DestinationScreen()
,
),
);
,
child: Card(
...someCardContent
),
),
)
目标屏幕
@override
Widget build(BuildContext context)
return Hero(
tag: 'heroTag_destinationScreen',
child: Scaffold(
appBar: ...someAppBar
body: ...someMainBodyContent
),
)
然后我环顾四周,有一个由 Flutter 团队创建的包,可以使用容器变换来模拟这种效果。我实现了它,效果很棒,但是我无法从左侧滑动 iOS 以返回并将布局缩小到卡片视图。
https://pub.dev/packages/animations
【问题讨论】:
卡顿很可能是由于应用程序的调试版本造成的。在配置文件或发布模式下重试 嗨,对不起,我的意思是 jank 没有我想要的过渡动画,即打开卡片,如显示效果并在初始化时反弹目标屏幕 我设法模拟了向后滑动并缓慢缩放脚手架,但在导航器弹出时脚手架突然放大到全屏 @FadhliS 你能分享你在动画包中使用的代码吗? 【参考方案1】:这是我的解决方案。
https://imgur.com/2WYn6TX
(对不起我的名誉,我无法发布图片。)
我自定义了英雄转场,尽可能地重做应用商店转场。
child: Hero(
tag: widget.product.id,
child: Image.asset(widget.product.image, fit: BoxFit.cover),
flightShuttleBuilder:
(flightContext, animation, direction, fromcontext, toContext)
final Hero toHero = toContext.widget;
// Change push and pop animation.
return direction == HeroFlightDirection.push
? ScaleTransition(
scale: animation.drive(
Tween<double>(
begin: 0.75,
end: 1.02,
).chain(
CurveTween(
curve: Interval(0.4, 1.0, curve: Curves.easeInOut)),
),
),
child: toHero.child,
)
: SizeTransition(
sizeFactor: animation,
child: toHero.child,
);
,
),
接下来,我使用ScaleTransition
和onVerticalDragUpdate
来控制pop动画。
https://imgur.com/a/xEMYOPr
double _initPoint = 0;
double _pointerDistance = 0;
GestureDetector(
onVerticalDragDown: (detail)
_initPoint = detail.globalPosition.dy;
,
onVerticalDragUpdate: (detail)
_pointerDistance = detail.globalPosition.dy - _initPoint;
if (_pointerDistance >= 0 && _pointerDistance < 200)
// scroll up
double _scaleValue = double.parse((_pointerDistance / 100).toStringAsFixed(2));
if (_pointerDistance < 100)
_closeController.animateTo(_scaleValue,
duration: Duration(milliseconds: 300),
curve: Curves.linear);
else if (_pointerDistance >= 260)
if (_pop)
_pop = false;
_closeController.fling(velocity: 1).then((_)
setState(()
_heightController.reverse();
);
Timer(Duration(milliseconds: 100), ()
Navigator.of(context).pop();
);
);
else
// scroll down
,
onVerticalDragEnd: (detail)
if (_pointerDistance >= 550)
if (_pop)
_closeController.fling(velocity: 1).then((_)
setState(()
_heightController.reverse();
);
Timer(Duration(milliseconds: 100), ()
Navigator.of(context).pop();
);
);
else
_closeController.fling(velocity: -1);
,
child: Hero(
tag: _product.id,
child: Image.asset(
_product.image,
fit: BoxFit.cover,
height: 300,
),
),
),
如果使用Hero
作为动画,则需要自定义文本部分的过渡。
这里:https://imgur.com/a/gyD6tiZ
在我的例子中,我通过 Sizetransition
控制文本部分的转换。
// horizontal way and vertical way.
SizeTransition(
axis: Axis.horizontal,
sizeFactor: Tween<double>(begin: 0.5, end: 1).animate(
CurvedAnimation(
curve: Curves.easeInOut, parent: _widthController),
),
child: SizeTransition(
sizeFactor: Tween<double>(begin: 0, end: 1).animate(
CurvedAnimation(
curve: Curves.easeInOut, parent: _heightController),
),
child: Container(
padding: EdgeInsets.only(
left: 20, right: 20, top: 50, bottom: 30),
width: double.infinity,
color: Colors.white,
constraints: BoxConstraints(
minHeight: 650,
),
child: Column(
// title and text
children: <Widget>[
Text('Title', style: TextStyle(fontSize: 18)),
SizedBox(height: 30),
Text(_text,
style: TextStyle(
fontSize: 15,
)),
],
),
),
),
),
虽然和App Store不一样,但希望对你有所帮助。
源码:https://github.com/HelloJunWei/app_store_transition
如果您有任何建议,请随时反馈或创建拉取请求。 :)
【讨论】:
您好,非常感谢您的努力!我设法使它也能正常工作,但我认为您的解决方案更好。我认为在关闭时仍然可以使边缘变圆作为您的阻力。也许我可以在你的 git 上创建一个拉取请求 嗨@FadhliS,我已经更新了我的项目。 demo gif 嗨@Neil,干得好!我面临着类似的问题,无法完成......看起来你真的很了解你的东西,所以你能看看吗? :) ***.com/questions/66438581/…以上是关于可以使用 Flutter 复制 iOS App Store 过渡吗?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter objectbox:我可以用于生产 APP(仅限移动设备 Android 和 iOS)
Flutter Add-to-app 我可以在 iOS 视图控制器中添加半屏 Flutter 小部件吗
Flutter:Runner.app/Info.plist 不存在。 Flutter“精简二进制”构建阶段必须在“复制捆绑资源”之后运行