我BottomNavigationBar
在颤振应用程序中实现了(BNB),但我遇到的问题是,当我想从 访问屏幕时AppDrawer
,它只会刷新当前屏幕,仅此而已。我已经把Navigator
内部放在了Indexed Stack
,所以每个屏幕都“堆叠”在彼此的顶部,每次我“调用”一个屏幕时,它都会在 UI 中呈现,BNB 是一致的。但就像我说的,当我从 调用同一个屏幕时AppDrawer
,会刷新同一个页面。我知道在应用程序启动时调用所有屏幕会减慢同一个应用程序的速度,但我没有看到更好的解决方案让 BNB 在所有页面上都保持不变。由于这是我的第一个应用程序,我正在为该应用程序的导航而苦苦挣扎,因此感谢任何形式的帮助。除了上面的解释之外,这是代码中包含一些注释的代码:
import 'dart:async';
import 'package:flutter/material.dart';
/// using a Navigator widget for navigation throughout the other widgets
class Navigation {
final Widget widget;
final GlobalKey<NavigatorState> navigationKey;
Navigation({this.widget, this.navigationKey});
}
class BottomNavBar extends StatefulWidget {
static const String id = 'bottom_navbar_screen';
@override
_BottomNavBarState createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
int _selectedIndex = 0;
/// list of screen that will render inside the BNB
List<Navigation> _items = [
Navigation(
widget: Screen1(), navigationKey: GlobalKey<NavigatorState>()),
Navigation(
widget: Screen2(), navigationKey: GlobalKey<NavigatorState>()),
Navigation(
widget: Screen3(), navigationKey: GlobalKey<NavigatorState>()),
Navigation(
widget: Screen4(), navigationKey: GlobalKey<NavigatorState>()),
Navigation(
widget: Screen5(), navigationKey: GlobalKey<NavigatorState>()),
];
/// function that renders components based on selected one in the BNB
void _onItemTapped(int index) {
if (index == _selectedIndex) {
_items[index]
.navigationKey
.currentState
.popUntil((route) => route.isFirst);
} else {
setState(() {
_selectedIndex = index;
});
}
}
/// navigation Tab widget for a list of all the screens and puts them in a Indexed Stack
Widget _navigationTab(
{GlobalKey<NavigatorState> navigationKey, Widget widget}) {
return Navigator(
key: navigationKey,
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(builder: (context) => widget);
},
);
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
final isFirstRouteInCurrentTab =
!await _items[_selectedIndex].navigationKey.currentState.maybePop();
if (isFirstRouteInCurrentTab) {
if (_selectedIndex != 0) {
_onItemTapped(1);
return false;
}
}
/// let system handle back button if we're on the first route
return isFirstRouteInCurrentTab;
},
child: Scaffold(
body: IndexedStack(
index: _selectedIndex,
children: _items
.map((e) => _navigationTab(
navigationKey: e.navigationKey, widget: e.widget))
.toList(),
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
label: 1,
),
BottomNavigationBarItem(
label: 2,
),
BottomNavigationBarItem(
label: 3,
),
BottomNavigationBarItem(
label: 4,
),
BottomNavigationBarItem(
label: 5,
),
],
currentIndex: _selectedIndex,
showUnselectedLabels: true,
onTap: _onItemTapped,
),
),
);
}
}
我想从那里访问 BNB 内的相同路由的基本AppDrawer
信息(而 BNB 仍然在屏幕上持续存在):
import 'package:flutter/material.dart';
import 'screen1';
import 'screen2';
import 'screen3';
class AppDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
DrawerHeader(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: [
CircleAvatar(
radius: 45,
backgroundColor: Colors.white,
backgroundImage: NetworkImage(imageUrl),
),
SizedBox(
height: 5,
),
Text(appDesc)
],
),
decoration: BoxDecoration(
color: Colors.grey[300],
),
),
ListTile(
title: Text('Screen1'),
onTap: () {
Navigator.pushNamed(context, Screen1.id);
},
),
ListTile(
title: Text('Screen2'),
onTap: () {
Navigator.pushNamed(context, Screen2.id);
},
),
ListTile(
title: Text('Screen3'),
onTap: () {
Navigator.pushNamed(context, Screen3.id);
},
),
],
),
);
}
}
Flutters Navigation 有更优雅的解决方案吗?我不想使用一些可能会在以后破坏应用程序的“黑客”,但在这一点上,为了继续前进,我可以尝试任何事情......
在此先感谢您的帮助!