我已向我的 Flutter Web 应用程序添加了底部导航。我还有一个侧抽屉,里面有其他菜单项。
底部导航栏效果很好,但如果我单击侧抽屉中的任何链接,我就会丢失底部导航栏,当我单击返回时,我会进入登录页面,而不是上一页。
当用户登录应用程序时,他们将被带到具有底部导航栏的主屏幕。
这是 main_screen.dart 的代码:
final List<Widget> appScreens = [
const CompanyDashboardScreen(),
const TransactionDetailScreen(true, true),
const AppointmentCalendarScreen(),
const UserProfileScreen(),
const ChatScreen(),
];
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
ensureScreenSize: true,
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: const CustomAppBar(),
body: SafeArea(child: Container(child: appScreens[_pageIndex])),
drawer: const SideDrawer(),
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.white,
selectedIconTheme: const IconThemeData(color: Colors.red),
selectedItemColor: Colors.red,
unselectedItemColor: Colors.black45,
type: BottomNavigationBarType.fixed,
currentIndex: _pageIndex,
onTap: (value) {
setState(() {
_pageIndex = value;
});
if (value == 3) {
ref.read(globalsNotifierProvider.notifier).updatenewUser(false);
}
},
///
/// Bottom Navigation Bar items
///
items: const [
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.house), label: "Home"),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.fileInvoiceDollar),
label: "Trxn"),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.calendar), label: "Calendar"),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.person), label: "User Profile"),
BottomNavigationBarItem(icon: Icon(Icons.chat), label: 'Chat'),
],
),
),
),
);
}
// Added this for BottomNavigationBar sync
void setIndex(int index) {
if (mounted) setState(() => _pageIndex = index);
}
}
///
/// Side drawer menu items
///
class SideDrawer extends StatelessWidget {
const SideDrawer({super.key});
@override
Widget build(BuildContext context) {
return Drawer(
child: (ListView(
padding: EdgeInsets.zero,
children: [
UserAccountsDrawerHeader(
accountName: Text("$userFName $userLName"),
accountEmail: Text(auth.currentUser!.email ?? 'No Email Found'),
),
Column(
children: <Widget>[
ListTile(
leading: const Icon(
Icons.add_business,
color: Colors.blueAccent,
),
title: const Text('Edit Company'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const CompanyScreen(false)));
},
),
ListTile(
leading: const Icon(
Icons.person,
color: Colors.lightBlueAccent,
),
title: const Text('Add Company Agent'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const UserProfileScreen(true),
),
);
},
),
ListTile(
leading: const Icon(
Icons.account_balance,
color: Colors.lightBlueAccent,
),
title: const Text('View Mortgage Companies'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const ListOfMortgageCompaniesScreen(),
),
);
},
),
ListTile(
leading: const Icon(
Icons.person_outline_sharp,
color: Colors.lightBlueAccent,
),
title: const Text('View Clients'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ListOfClientsScreen(),
),
);
},
),
ListTile(
leading: const FaIcon(FontAwesomeIcons.businessTime),
title: const Text('View Title Companies'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ListOfTitleCompaniesScreen(),
),
);
},
),
ListTile(
leading: const FaIcon(FontAwesomeIcons.personWalking),
title: const Text('View Appraiser Companies'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const ListOfAppraiserCompaniesScreen(),
),
);
},
),
ListTile(
leading: const FaIcon(FontAwesomeIcons.peopleCarryBox),
title: const Text('View Inspector Companies'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const ListOfInspectorCompaniesScreen(),
),
);
},
),
ListTile(
leading: const FaIcon(FontAwesomeIcons.calculator),
title: const Text('Mortgage Calculator'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const MortgageCalculatorScreen()));
},
),
ListTile(
leading: const FaIcon(FontAwesomeIcons.dollarSign),
title: const Text('Pricing'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const MortgageCalculatorScreen()));
},
),
ListTile(
leading: const FaIcon(FontAwesomeIcons.lock),
title: const Text(
'Privacy Policy',
style: TextStyle(
color: Colors.blue, decoration: TextDecoration.underline),
),
onTap: () {
if (kIsWeb) {
_launchInBrowser();
} else {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const PrivacyPolicyScreen()));
}
},
),
ListTile(
leading: const Icon(
Icons.logout,
color: Colors.red,
),
title: const Text('Log Out'),
onTap: () {
// Update the state of the app
signOut();
// Then close the drawer
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const LoginScreen()));
},
),
],
),
],
)),
);
}
那么,如何让从侧抽屉显示的页面仍然显示底部导航栏?
如何让侧边抽屉菜单显示的页面在单击后退按钮时返回到上一页?
亲爱的,请确保您已在第一个父页面中添加了 BottomNavigationBar,例如
class DashBoardScreenState extends State<DashBoardScreen> {
final PageController _pageController = PageController();
int _pageIndex = 2;
late List<Widget> _screens;
final GlobalKey<ScaffoldMessengerState> _scaffoldKey = GlobalKey();
bool singleVendor = false;
@override
void initState() {
super.initState();
singleVendor = Provider.of<SplashProvider>(context, listen: false)
.configModel!
.businessMode ==
"single";
_screens = [
singleVendor
? const PetListingScreen()
: const OrderScreen(isBacButtonExist: false),
const AllBlogsScreen(),
const HomePage(),
singleVendor
?
const MyPetList()
: const OrderScreen(isBacButtonExist: false),
singleVendor
? const MoreScreen()
:
const MyPetList(),
singleVendor ? const SizedBox() : const MoreScreen(),
];
NetworkInfo.checkConnectivity(context);
}
@override
Widget build(BuildContext context) {
bool isDarkMode = Provider.of<ThemeProvider>(context).darkTheme;
return WillPopScope(
onWillPop: () async {
if (_pageIndex != 2) {
_setPage(2);
return false;
} else {
return true;
}
},
child: Scaffold(
key: _scaffoldKey,
bottomNavigationBar: ClipRRect(
borderRadius: BorderRadius.only(
topRight: Radius.circular(18), topLeft: Radius.circular(18)),
child: GNav(
rippleColor: Colors.grey[300]!,
hoverColor: Colors.grey[100]!,
gap: 7,
backgroundColor: Theme.of(context).primaryColor,
activeColor: isDarkMode ? Colors.black : Colors.white,
iconSize: 17,
padding: EdgeInsets.symmetric(horizontal: 14, vertical: 11),
tabMargin: EdgeInsets.symmetric(vertical: 8, horizontal: 4),
duration: Duration(milliseconds: 600),
tabBackgroundColor: isDarkMode ? Colors.white : Colors.black45,
tabActiveBorder:
Border.all(color: isDarkMode ? Colors.black26 : Colors.black54),
color: isDarkMode ? Colors.black : Colors.white,
textSize: 17,
tabs: _getBottomIcons(singleVendor),
selectedIndex: _pageIndex,
onTabChange: (index) {
setState(() {
_pageIndex = index;
});
},
),
),
body: PageView.builder(
controller: _pageController,
itemCount: _screens.length,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return _screens[_pageIndex];
},
),
),
);
}
Image _NavBarItem(String icon, int index) {
return Image.asset(
icon,
color: index == _pageIndex ? Colors.white : Colors.white.withOpacity(0.5),
height: 25,
width: 25,
);
}
void _setPage(int pageIndex) {
setState(() {
_pageController.jumpToPage(pageIndex);
_pageIndex = pageIndex;
});
}
List<GButton> _getBottomIcons(bool isSingleVendor) {
List<GButton> list = [];
if (!isSingleVendor) {
list.add(GButton(
icon: FontAwesomeIcons.paw, text: getTranslated('my_pet', context)!));
list.add(GButton(
icon: FontAwesomeIcons.inbox,
text: getTranslated('inbox', context)!));
list.add(GButton(
icon: Icons.move_to_inbox, text: getTranslated('blogs', context)!));
list.add(GButton(
icon: FontAwesomeIcons.house, text: getTranslated('home', context)!));
list.add(GButton(
icon: FontAwesomeIcons.a, text: getTranslated('add_new', context)!));
list.add(GButton(
icon: FontAwesomeIcons.a, text: getTranslated('more', context)!));
} else {
list.add(GButton(
icon: FontAwesomeIcons.paw, text: getTranslated('my_pet', context)!));
list.add(GButton(
icon: FontAwesomeIcons.fileInvoice,
text: getTranslated('blogs', context)!));
list.add(GButton(
icon: FontAwesomeIcons.house, text: getTranslated('home', context)!));
list.add(GButton(
icon: FontAwesomeIcons.cat,
text: getTranslated('add_new', context)!));
list.add(GButton(
icon: CupertinoIcons.rectangle_grid_2x2_fill,
text: getTranslated('more', context)!));
}
return list;
}
}
在这里您可以看到最重要的一个屏幕没有移动任何地方,但屏幕正在成为其脚手架主体的一部分。
在这里您还提到您将直接返回登录页面,因此 在重定向到抽屉磁贴中的任何页面之前,尝试删除 Navigator.pop(context);
也许它在预测之前就杀死了当前的上下文