Flutter:保留 BottomNavigationBar 并根据 BottomNavigationBar 的选定索引将用户路由到正确的屏幕
Flutter: Persist BottomNavigationBar and route user to the correct screen depending on the selected index of the BottomNavigationBar
我希望 BottomNavigationBar 持续存在,并根据用户选择的索引以及 BottomNavigationBar 上突出显示的索引将用户发送到不同的屏幕。
我尝试这样做的方法是根据 BottomNavigationBar()
当前选择的索引更改 Scaffold
的正文值。一旦选择了 BottomNavigationBar()
的选定索引,我就可以突出显示它,但是正文没有路由到适当的小部件。
BottomNavBar
中 onTap:
引用的当前方法正确突出显示了选定的索引,但没有路由到正确的小部件。
我的 BottomNavBar
中有一个未使用的方法 (_switchScreen
)。将此作为 BottomNavBar()
的 onTap:
的值适当地路由到正确的屏幕,但随后我必须在每个视图上重建 BottomNavBar
并且在 BottomNavBar
后面无法访问在 NavModel
(导航模型)中引用。
这是我的 BottomNavBar()
:
import 'package:flutter/material.dart';
import '../screens/Add_Media_Screen.dart';
import '../screens/Profile_Screen.dart';
import '../screens/Venture_Feed_Screen.dart';
class BottomNavBar extends StatefulWidget {
@override
_BottomNavBarState createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
void _switchScreen(index) {
switch (index) {
case 0:
Navigator.pushNamed(context, VentureFeedScreen.routeName);
break;
case 1:
Navigator.pushNamed(context, ProfileScreen.routeName);
break;
case 2:
Navigator.pushNamed(context, AddMediaScreen.routeName);
break;
}
}
@override
Widget build(BuildContext context) {
return Theme(
data: ThemeData(
primaryColor: Color(0xff84d1da),
accentColor: Color(0xff62c2a2),
),
child: BottomNavigationBar(
selectedItemColor: Color(0xff84d1da),
unselectedItemColor: Colors.grey,
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
//Index 0
BottomNavigationBarItem(
icon: Icon(
Icons.explore,
),
label: 'Discover',
),
//Index 1
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
// color: Color(0xff84d1da),
),
label: 'Profile',
// backgroundColor: Color(0xff84d1da),
),
//Index 2
BottomNavigationBarItem(
icon: Icon(
Icons.add_circle_outline,
),
label: 'Add Media',
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
);
}
}
这里是 NavModel
:
import 'package:flutter/material.dart';
import '../screens/Profile_Screen.dart';
import '../screens/Venture_Feed_Screen.dart';
import '../screens/Add_Media_Screen.dart';
import '../widgets/BottomNavBar.dart';
class NavModel extends StatefulWidget {
static const routeName = '/nav-model';
@override
_NavModelState createState() => _NavModelState();
}
class _NavModelState extends State<NavModel> {
int _currentIndex = 0;
final tabs = [
VentureFeedScreen(),
ProfileScreen(),
AddMediaScreen(),
];
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: tabs[_currentIndex],
bottomNavigationBar: BottomNavBar(),
),
);
}
}
我认为您想要完成的是 PageView class 的行为,对吗?将 PageView 作为脚手架的主体,并将 tabs
作为子项传递给 PageView。
将其拆分为两个不同的 classes 在这种情况下不起作用。在 NavModel()
class body:
属性 的 Scaffold
中,我试图根据 tabs
列表更新值_currentIndex
的静态索引值为 0。我认为通过调用 BottomNavBar()
class 并将 onTap:
值设置为根据 _onItemTapped
进行更新方法,它将根据 BottomNavBar
class 中 _onItemTapped
方法中定义的内容更新 body:
值。这是不正确的。
代码 运行 与我定义的一样正确:脚手架的 body: tabs[_currentIndex]
正在调用正确的逻辑 - 在选项卡列表的 0 索引处显示该项目。当发生这种情况时,BottomNavBar 的索引正在更新以反映正确的用户选择的索引和值,从而导致混淆为什么 BottomNavBar 选择的索引正在更新而 Scaffold
的主体保持不变。
正确代码如下:
class BottomNavBar extends StatefulWidget {
static const routeName = '/navigator-model';
@override
_BottomNavBarState createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
final List<Widget> tabs = [
VentureFeedScreen(),
ProfileScreen(),
AddMediaScreen(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: tabs.elementAt(_selectedIndex),
bottomNavigationBar: BottomNavigationBar(
selectedItemColor: Color(0xff84d1da),
unselectedItemColor: Colors.grey,
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
//Index 0
BottomNavigationBarItem(
icon: Icon(
Icons.explore,
),
label: 'Discover',
),
//Index 1
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
// color: Color(0xff84d1da),
),
label: 'Profile',
// backgroundColor: Color(0xff84d1da),
),
//Index 2
BottomNavigationBarItem(
icon: Icon(
Icons.add_circle_outline,
),
label: 'Add Media',
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
);
}
}
但是,我还没有看到 BottomNavBar
是否继续导航到另一个屏幕(尚未构建该功能)。
我希望 BottomNavigationBar 持续存在,并根据用户选择的索引以及 BottomNavigationBar 上突出显示的索引将用户发送到不同的屏幕。
我尝试这样做的方法是根据 BottomNavigationBar()
当前选择的索引更改 Scaffold
的正文值。一旦选择了 BottomNavigationBar()
的选定索引,我就可以突出显示它,但是正文没有路由到适当的小部件。
BottomNavBar
中 onTap:
引用的当前方法正确突出显示了选定的索引,但没有路由到正确的小部件。
我的 BottomNavBar
中有一个未使用的方法 (_switchScreen
)。将此作为 BottomNavBar()
的 onTap:
的值适当地路由到正确的屏幕,但随后我必须在每个视图上重建 BottomNavBar
并且在 BottomNavBar
后面无法访问在 NavModel
(导航模型)中引用。
这是我的 BottomNavBar()
:
import 'package:flutter/material.dart';
import '../screens/Add_Media_Screen.dart';
import '../screens/Profile_Screen.dart';
import '../screens/Venture_Feed_Screen.dart';
class BottomNavBar extends StatefulWidget {
@override
_BottomNavBarState createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
void _switchScreen(index) {
switch (index) {
case 0:
Navigator.pushNamed(context, VentureFeedScreen.routeName);
break;
case 1:
Navigator.pushNamed(context, ProfileScreen.routeName);
break;
case 2:
Navigator.pushNamed(context, AddMediaScreen.routeName);
break;
}
}
@override
Widget build(BuildContext context) {
return Theme(
data: ThemeData(
primaryColor: Color(0xff84d1da),
accentColor: Color(0xff62c2a2),
),
child: BottomNavigationBar(
selectedItemColor: Color(0xff84d1da),
unselectedItemColor: Colors.grey,
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
//Index 0
BottomNavigationBarItem(
icon: Icon(
Icons.explore,
),
label: 'Discover',
),
//Index 1
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
// color: Color(0xff84d1da),
),
label: 'Profile',
// backgroundColor: Color(0xff84d1da),
),
//Index 2
BottomNavigationBarItem(
icon: Icon(
Icons.add_circle_outline,
),
label: 'Add Media',
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
);
}
}
这里是 NavModel
:
import 'package:flutter/material.dart';
import '../screens/Profile_Screen.dart';
import '../screens/Venture_Feed_Screen.dart';
import '../screens/Add_Media_Screen.dart';
import '../widgets/BottomNavBar.dart';
class NavModel extends StatefulWidget {
static const routeName = '/nav-model';
@override
_NavModelState createState() => _NavModelState();
}
class _NavModelState extends State<NavModel> {
int _currentIndex = 0;
final tabs = [
VentureFeedScreen(),
ProfileScreen(),
AddMediaScreen(),
];
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: tabs[_currentIndex],
bottomNavigationBar: BottomNavBar(),
),
);
}
}
我认为您想要完成的是 PageView class 的行为,对吗?将 PageView 作为脚手架的主体,并将 tabs
作为子项传递给 PageView。
将其拆分为两个不同的 classes 在这种情况下不起作用。在 NavModel()
class body:
属性 的 Scaffold
中,我试图根据 tabs
列表更新值_currentIndex
的静态索引值为 0。我认为通过调用 BottomNavBar()
class 并将 onTap:
值设置为根据 _onItemTapped
进行更新方法,它将根据 BottomNavBar
class 中 _onItemTapped
方法中定义的内容更新 body:
值。这是不正确的。
代码 运行 与我定义的一样正确:脚手架的 body: tabs[_currentIndex]
正在调用正确的逻辑 - 在选项卡列表的 0 索引处显示该项目。当发生这种情况时,BottomNavBar 的索引正在更新以反映正确的用户选择的索引和值,从而导致混淆为什么 BottomNavBar 选择的索引正在更新而 Scaffold
的主体保持不变。
正确代码如下:
class BottomNavBar extends StatefulWidget {
static const routeName = '/navigator-model';
@override
_BottomNavBarState createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
final List<Widget> tabs = [
VentureFeedScreen(),
ProfileScreen(),
AddMediaScreen(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: tabs.elementAt(_selectedIndex),
bottomNavigationBar: BottomNavigationBar(
selectedItemColor: Color(0xff84d1da),
unselectedItemColor: Colors.grey,
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
//Index 0
BottomNavigationBarItem(
icon: Icon(
Icons.explore,
),
label: 'Discover',
),
//Index 1
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
// color: Color(0xff84d1da),
),
label: 'Profile',
// backgroundColor: Color(0xff84d1da),
),
//Index 2
BottomNavigationBarItem(
icon: Icon(
Icons.add_circle_outline,
),
label: 'Add Media',
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
);
}
}
但是,我还没有看到 BottomNavBar
是否继续导航到另一个屏幕(尚未构建该功能)。