英文原文:Hero Animation not working inside nested Navigator 中文翻译:嵌套的导航器中的Hero动画不起作用
英文原文:Hero Animation not working inside nested Navigator 中文翻译:嵌套的导航器中的Hero动画不起作用
我正在尝试在我的第一个Flutter应用中使用Hero动画,但是已经有一个类似Instagram的底部导航栏,是使用这种方法实现的,并且我发现在嵌套的导航器中Hero动画根本不起作用。
例如,你可以从这里获取一个完整的示例,并将HeroApp
类中的home: MainScreen(),
替换为
home: Navigator(onGenerateRoute: (_) {
return MaterialPageRoute(builder: (_) => MainScreen());
}),
然后英雄动画就会失效。
也许还有其他方法来实现每个选项卡的独立堆栈的底部导航,而不使用嵌套的导航器,但我没有找到任何方法。
所以非常感谢任何建议。
更新:我刚刚意识到答案应该在MaterialApp
类中,太棒了!
有一个简单的解决方案可以工作:
home: Navigator(
onGenerateRoute: (_) => MaterialPageRoute(builder: (_) => MainScreen()),
observers: [HeroController()],
),
但在MaterialApp
源代码中,事情要复杂一些,所以也许有一些隐藏的东西破坏了我的简单解决方案。因此问题仍然没有解决。
问题原因:Hero动画在嵌套的Navigator中无法正常工作。
解决方法:
1. 在2022年8月的更新中,提供了一个更好的解决方案,即在每个Navigator小部件中包装一个HeroControllerScope小部件。具体做法是:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
builder: (BuildContext context, Widget child) {
// 构建两个并行的导航器。
return Stack(
children:
HeroControllerScope(
controller: MaterialApp.createMaterialHeroController(),
child: Navigator(
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute
settings: settings,
builder: (BuildContext context) {
return const Text('first Navigator');
}
);
},
),
),
HeroControllerScope(
controller: MaterialApp.createMaterialHeroController(),
child: Navigator(
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute
settings: settings,
builder: (BuildContext context) {
return const Text('second Navigator');
}
);
},
),
),
],
);
}
)
);
}
2. 在Navigator 2.0上不起作用。
3. 这个解决方法非常接近实际工作的解决方案,但通常应该将HeroController作为小部件的状态中的最终变量创建。
这个问题的出现的原因是因为Hero动画依赖于一个HeroController,而MaterialApp中的Navigator有这个控制器,但是自定义的Navigator没有,要解决这个问题,只需添加控制器,像这样。
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
_HomeState createState() => _HomeState();
}
class _HomeState extends State
HeroController _heroController;
void initState() {
super.initState();
_heroController = HeroController(createRectTween: _createRectTween);
}
Widget build(BuildContext context) {
return Navigator(
observers: [_heroController],
onGenerateRoute: (settings) {
return MaterialPageRoute(
settings: settings, builder: (context) => Text(''));
},
);
}
RectTween _createRectTween(Rect begin, Rect end) {
return MaterialRectArcTween(begin: begin, end: end);
}
}
考虑重构以使用HeroControllerScope小部件。