【发布时间】:2022-08-22 22:38:12
【问题描述】:
我有一个带有BottomNavigationBar 和IndexedStack 的应用程序,它显示了标签内容。每个选项卡都有自己的Router 和自己的RouterDelegate,以模仿 iOS 样式的选项卡行为(每个选项卡都有自己的导航控制器)。
之前,这个应用程序只在 iOS 上发布。我现在正在开发Android版本,需要正确支持Android硬件后退按钮。我通过为每个标签实现一个ChildBackButtonDispatchers 来做到这一点,它是父RootBackButtonDispatcher 的一个子标签。这行得通。
我现在遇到的问题是我使用WillPopScope 小部件在用户离开屏幕时保存他们的输入。如果用户点击AppBar 中的后退按钮,这将正常工作,但当用户点击硬件后退按钮时不会触发回调。我也在这些屏幕上实现了BackButtonListeners,但这意味着我必须将屏幕包装在WillPopScopes 和BackButtonListeners 中,两者都调用相同的回调。
它应该是这样,还是我做错了什么?
相关的小部件层次结构:
MaterialAppNavigator- 标签界面与
IndexedStack - 选中的标签小部件标签的
Router Navigator- 多页,在堆栈的最后一页...
BackButtonListenerWillPopScope-
Scaffold
我的(简化的)路由器委托如下所示:
class AppRouterDelegate extends RouterDelegate<AppRoute>
with ChangeNotifier, PopNavigatorRouterDelegateMixin<AppRoute> {
AppRouterDelegate({
List<MaterialPage> initialPages = const [],
}) : _pages = initialPages;
final navigatorKey = GlobalKey<NavigatorState>();
final List<MaterialPage> _pages;
List<MaterialPage> get pages => List.unmodifiable(_pages);
void push(AppRoute route) {
final shouldAddPage = _pages.isEmpty || (_pages.last.arguments as AppRoute != route);
if (!shouldAddPage) {
return;
}
_pages.add(route.page);
notifyListeners();
}
@override
Future<void> setNewRoutePath(AppRoute route) async {
_pages.clear();
_pages.add(route.page);
notifyListeners();
return SynchronousFuture(null);
}
@override
Future<bool> popRoute() {
if (canPop) {
pop();
return SynchronousFuture(true);
}
return SynchronousFuture(false);
}
bool get canPop => _pages.length > 1;
void pop() {
if (canPop) {
_pages.remove(_pages.last);
notifyListeners();
}
}
void popTillRoot() {
while (canPop) {
_pages.remove(_pages.last);
}
notifyListeners();
}
bool _onPopPage(Route<dynamic> route, result) {
final didPop = route.didPop(result);
if (!didPop) {
return false;
}
if (canPop) {
pop();
return true;
} else {
return false;
}
}
@override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
onPopPage: _onPopPage,
pages: pages,
);
}
}
我找到了this Flutter issue,这让我觉得我根本不应该拥有 WillPopScope,但是没有它,AppBar 中的水龙头就不会被抓住......
标签: flutter