我需要在每个选项卡内有一个导航器,因此当我推送新的小部件时,选项卡栏会保留在屏幕上。代码运行得很好,但是 android 后退按钮正在关闭应用程序而不是运行 Navigator.pop()
import 'package:flutter/material.dart';
void main() {
runApp(const TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
const TabBarDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 1,
child: Scaffold(
bottomNavigationBar: const BottomAppBar(
color: Colors.black,
child: TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
],
),
),
body: TabBarView(
children: [
Navigator(
onGenerateRoute: (settings) {
return MaterialPageRoute(
builder: (context) => IconButton(
icon: Icon(Icons.directions_car),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => newPage()))),
);
},
),
],
),
),
),
);
}
}
class newPage extends StatelessWidget {
const newPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("new page"),
),
body: Center(child: Icon(Icons.add)),
);
}
}
代码也可用 here 但在 dartpad 上你无法测试 Android 后退按钮。
首先您应该为您的导航器创建一个密钥
final GlobalKey<NavigatorState> homeNavigatorKey = GlobalKey();
然后将此键添加到您的导航器中
Navigator(
key: homeNavigatorKey,
然后将您的
Navigator
包装在 WillPopScope
小部件中,并添加 onWillPop
,如下所示
child: WillPopScope(
onWillPop: () async {
return !(await homeNavigatorKey.currentState!.maybePop());
},
child: Navigator(
key: homeNavigatorKey,
这将检查
navigatorKey
是否可以弹出一条路线,如果是,它只会弹出此路线,如果不是,它会弹出自己,从而关闭应用程序
基于奥马尔·哈特姆的回答
在TabBarController状态下:
final GlobalKey<NavigatorState> screenANavigatorKey = GlobalKey();
final GlobalKey<NavigatorState> screenBNavigatorKey = GlobalKey();
辅助功能:
GlobalKey<NavigatorState> indexToNavigatorKey(int index) {
switch (index) {
case 0: return screenANavigatorKey;
case 1: return screenBNavigatorKey;
}
}
在
WillPopScope.onWillPop
:
// I am saving the current screen index in some variable
GlobalKey<NavigatorState> subScreenNavigatorKey = indexToNavigatorKey(currentScreen);
await subScreenNavigatorKey.currentState?.maybePop();
return ...
WillPopScope
的孩子:
CupertinoTabScaffold(
controller: _controller,
tabBuilder: (context, index) =>
CupertinoTabView(
navigatorKey: screenToNavigatorKey(index),
builder: (context) => // your current screen goes here
家居集团:
GlobalKey<NavigatorState>? navigatorPage1Key;
GlobalKey<NavigatorState>? navigatorPage2Key;
GlobalKey<NavigatorState>? navigatorPage3Key;
GlobalKey<NavigatorState>? navigatorPage4Key;
GlobalKey<NavigatorState>? navigatorPage5Key;
var pageIndex = 0;
我的主页有子页面,例如 page1、page2、page3....
在主页:
return WillPopScope(
onWillPop: () async {
switch (homeBloc.pageIndex) {
case 0:
return !(await homeBloc.navigatorPage1Key!.currentState!.maybePop());
case 1:
return !(await homeBloc.navigatorPage2Key!.currentState!.maybePop());
case 2:
return !(await homeBloc.navigatorPage3Key!.currentState!.maybePop());
case 3:
return !(await homeBloc.navigatorPage4Key!.currentState!.maybePop());
case 4:
return !(await homeBloc.navigatorPage5Key!.currentState!.maybePop());
}
return true;
},
child: BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
return Scaffold(
body: Material(
child: Column(
children: [
Expanded(
child: Container(
decoration: const BoxDecoration(
color: AppColors.backgroundPrimary,
),
child: IndexedStack(
sizing: StackFit.expand,
index: homeBloc.pageIndex,
children: <TabCustomWidget>[
TabCustomWidget(
tab: const Page1(),
navigatorKey: homeBloc.navigatorPage1Key,
),
TabCustomWidget(
tab: const Page2(),
navigatorKey: homeBloc.navigatorPage2Key,
),
TabCustomWidget(
tab: const Page3(),
navigatorKey: homeBloc.navigatorPage3Key,
),
TabCustomWidget(
tab: const Page4(),
navigatorKey: homeBloc.navigatorPage4Key,
),
TabCustomWidget(
tab: const Page5(),
navigatorKey: homeBloc.navigatorPage5Key,
),
],
),
),
),
Visibility(
visible: state.isViewBottomNavigator,
child: const BottomNavigationBarWidget(),
),
],
),
),
);
},
),
);
基本我的
TabCustomWidget
:
class TabCustomWidget extends StatelessWidget {
final Widget tab;
final String tabKeyLogger;
final GlobalKey<NavigatorState>? navigatorKey;
const TabCustomWidget({
super.key,
required this.tab,
required this.tabKeyLogger,
this.navigatorKey,
});
@override
Widget build(BuildContext context) {
return CupertinoTabView(
builder: (context) => tab,
routes: AppRoutes.routes,
navigatorKey: navigatorKey,
navigatorObservers: [RouteObserver(tabKeyLogger, context)],
);
}
}
基本我的
RouteObserver
:
class RouteObserver extends NavigatorObserver {
final String tabKey;
final BuildContext context;
RouteObserver(this.tabKey, this.context);
@override
void didPush(Route route, Route? previousRoute) {
super.didPush(route, previousRoute);
log('[TAB-NAVIGATOR] [$tabKey] [PUSH] ${route.settings.name}');
if (route.settings.name!.startsWith('drawer')) {
context.read<HomeBloc>().add(const OnHideBottomNavigatorHomeEvent());
}
}
@override
void didPop(Route route, Route? previousRoute) {
super.didPop(route, previousRoute);
log('[TAB-NAVIGATOR] [$tabKey] [POP] ${route.settings.name}');
if (route.settings.name!.startsWith('drawer')) {
context.read<HomeBloc>().add(const OnShowBottomNavigatorHomeEvent());
}
}
}