给出2条路线,例如父和子以及带有相同标签的Hero(..)小部件。
当用户在“父”屏幕上并打开“子”时,将对Hero小部件进行动画处理。当它返回时(通过Navigator.pop
),它也具有动画效果。
我正在寻找一种在回退时(通过Navigator.pop
从孩子到父母)禁用该动画的方法。
有没有一种在小部件上被动画化之前会被其调用的处理程序?然后,我可能可以更改Hero
标签并解决问题。
或者,当在父窗口小部件中为路由创建“构建器”时,我可能会记住对目标窗口小部件的引用,并在调用Navigator.pop
之前通知它“您将被动画化”。这还需要使该小部件成为有状态的(我还没有找到一种方法来强制重建无状态小部件)。
有没有更简单的方法来实现这一点?
答案 0 :(得分:0)
目前我唯一能想到的方法是以一种似乎没有动画效果的方式“动画化”弹出的英雄,让我们检查一下这段代码:
class SecondRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Hero(
flightShuttleBuilder: (context, anim, direction, fromContext, toContext) {
final Hero toHero = toContext.widget;
if (direction == HeroFlightDirection.pop) {
return FadeTransition(
opacity: AlwaysStoppedAnimation(0),
child: toHero.child,
);
} else {
return toHero.child;
}
},
child: FlatButton(
child: Text("prev 1"),
onPressed: () {
Navigator.of(context).pop();
},
),
tag: "test",
));
}
}
在您的SecondRoute(应该弹出的那个)中,您必须向flightShuttleBuilder
提供一个Hero
参数,然后您才能检查方向,如果它正在弹出,只需用一个{ {1}}淡入淡出过渡
我希望这是预期的结果,当然,您可以完全更改flightShuttleBuilder内部的过渡以改变效果!由您决定:)
答案 1 :(得分:0)
尽管目前尚无内置方法可以在任何特定方向上禁用Hero动画,尽管CLucera将FadeTransition
与HeroFlightDirection
结合使用是一种创造性的方法,但最直接的方法是打破两个英雄之间的tag
关联:
当您从第二英雄回到第一英雄时,只需将第一英雄的标签临时更改为其他标签,英雄就不会恢复动画。简化示例:
class _MyHomePageState extends State<MyHomePage> {
String tag1, tag2;
String sharedTag = 'test';
String breakTag = 'notTest';
@override
void initState() {
super.initState();
tag1 = sharedTag;
tag2 = sharedTag;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Hero(
tag: tag1,
child: RaisedButton(
child: Text("hi"),
onPressed: () {
// restore the tag
if (tag1 != sharedTag) {
setState(() {
tag1 = sharedTag;
});
}
// second route
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
alignment: Alignment.topLeft,
child: Hero(
tag: tag2,
child: RaisedButton(
child: Text('hello'),
onPressed: () {
// change the tag to disable the reverse anim
setState(() {
tag1 = breakTag;
});
Navigator.of(context).pop();
},
),
)
),
);
}
)
);
},
)
),
),
);
}
}
但是,如果您想直接修改动画,则可以像在CLucera中一样在flightShuttleBuilder
内播放。您还可以查看medium/mastering-hero-animations-in-flutter来进一步探索该区域。