【发布时间】:2023-01-03 21:02:00
【问题描述】:
如何根据导航为小部件设置动画?
因为当它第一次创建时,我们可以使用
animationController.forward(); 在 initState 中。
但是其他转换呢:
- 相同路线弹出
- 新路由推送
- 新路线流行
【问题讨论】:
标签: flutter flutter-animation flutter-navigation
如何根据导航为小部件设置动画?
因为当它第一次创建时,我们可以使用
animationController.forward(); 在 initState 中。
但是其他转换呢:
【问题讨论】:
标签: flutter flutter-animation flutter-navigation
采用路由观察者.
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
然后将其添加到根 materialApp 小部件:
MaterialApp(
theme: ThemeData(),
navigatorObservers: [routeObserver],
)
(以上代码摘自here)
然后你可以为上面的任何项目控制你的 AnimationController。
我的实现
创建一个 RouteAware AnimationController 小部件并将控制器和子项传递给它。
主要小部件构建:
return RouteAwareAnimationController(
controller: controller,
child: SizeTransition( // Or any other animation that's connected to the controller
RouteAwareAnimation 小部件
class RouteAwareAnimationController extends StatefulWidget {
const RouteAwareAnimationController({
Key? key,
required this.controller,
required this.child,
}) : super(key: key);
final AnimationController controller;
final Widget child;
@override
State<RouteAwareAnimationController> createState() => _RouteAwareAnimationControllerState();
}
class _RouteAwareAnimationControllerState extends State<RouteAwareAnimationController>
with RouteAware {
AnimationController get controller => widget.controller;
@override
Widget build(BuildContext context) {
return widget.child;
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
routeObserver.subscribe(
this, ModalRoute.of(context)! as PageRoute<dynamic>);
}
@override
// page push, same as using this in initState
void didPush() => controller.forward();
@override
// when this page is poped
void didPop() => controller.reverse();
@override
// when next page is pushed
void didPushNext() => controller.reverse();
@override
// when next page is poped
void didPopNext() => controller.forward();
@override
void dispose() {
routeObserver.unsubscribe(this);
super.dispose();
}
}
随意根据您的需要自定义它,或将 bool 值传递给它以启用或禁用某些操作。
更通用的解决方案
使用更通用的 RouteAwareWidget,以便您可以为每个特定的导航事件传递一个函数。
它可能看起来像这样:
class RouteAwareWidget extends StatefulWidget {
const RouteAwareWidget({
Key? key,
required this.child,
this.onPush,
this.onPop,
this.onPushNext,
this.onPopNext,
}) : super(key: key);
final Widget child;
final Function? onPush, onPop, onPushNext, onPopNext;
@override
State<RouteAwareWidget> createState() => _RouteAwareWidgetState();
}
class _RouteAwareWidgetState extends State<RouteAwareWidget> with RouteAware {
@override
Widget build(BuildContext context) {
return widget.child;
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
routeObserver.subscribe(
this, ModalRoute.of(context)! as PageRoute<dynamic>);
}
@override
// page push, same as using this in initState
void didPush() {
if (widget.onPush != null) widget.onPush!();
}
@override
// when this page is poped
void didPop() {
if (widget.onPop != null) widget.onPop!();
}
@override
// when next page is pushed
void didPushNext() {
if (widget.onPushNext != null) widget.onPushNext!();
}
@override
// when next page is poped
void didPopNext() {
if (widget.onPop != null) widget.onPopNext!();
}
@override
void dispose() {
routeObserver.unsubscribe(this);
super.dispose();
}
}
【讨论】: