我正在构建一个 flutter 应用程序,在某些时候,我必须添加一个底部工作表,所以我使用了“showModalBottomSheet”。我还想在其中显示一个导航栏,所以我添加了一个“BottomNavigationBar”的自定义小部件,现在我想根据底部导航栏的项目索引显示一些内容,如果 index = 1 显示a
Text("Home")
if index = 2 显示 ListView.builder()
这是我的 2 个小部件:
身体小部件
class BuildBody extends StatefulWidget {
final UserOfGift user;
final UserOfGift friend;
const BuildBody({
super.key,
required this.user,
required this.friend,
});
@override
State<BuildBody> createState() => _BuildBodyState();
}
class _BuildBodyState extends State<BuildBody> {
final DatabaseService _databaseService = DatabaseService();
bool isShown = true;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
Future displayBottomSheet() {
return showModalBottomSheet(
context: context,
backgroundColor: Pallete.pinkyPink,
showDragHandle: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(35))),
builder: (_) => Container(
constraints: const BoxConstraints(maxHeight: 450),
height: 350,
padding: const EdgeInsets.all(10),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: ListView.builder(
itemCount: widget.user.friendList.length,
itemBuilder: (context, index) {
String friendUid = widget.user.friendList[index];
return StreamBuilder(
stream: _databaseService.getUserDataStream(friendUid),
builder: (context, snapshot) {
if (snapshot.hasData) {
UserOfGift friendFromList = snapshot.data!;
return FriendListTile(user: friendFromList);
}
return const SizedBox();
},
);
},
)),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: BuildBottomNavBar(
myUser: widget.user,
),
),
)
],
),
));
}
return Center(
child: SizedBox(
height: screenSize.height,
width: screenSize.width,
child: GestureDetector(
onHorizontalDragEnd: (details) {
setState(() {
if (details.primaryVelocity! > 0) {
isShown = false;
} else if (details.primaryVelocity! < 0) {
isShown = true;
}
});
},
onVerticalDragEnd: (details) {
setState(() {
displayBottomSheet();
print("update with display");
});
},
...// the rest of my code
底部导航栏
class BuildBottomNavBar extends StatefulWidget {
final UserOfGift myUser;
const BuildBottomNavBar({
super.key,
required this.myUser,
});
@override
State<BuildBottomNavBar> createState() => _BuildBottomNavBarState();
}
class _BuildBottomNavBarState extends State<BuildBottomNavBar> {
int _currentIndex = 0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
print("BuildBottomNavState widget rebuilt");
return ClipRRect(
borderRadius: BorderRadius.circular(15),
child: SizedBox(
height: 60,
child: BottomNavigationBar(
selectedItemColor: Pallete.boldPink,
unselectedItemColor: Pallete.pinkyPink,
elevation: 10,
iconSize: 30,
currentIndex: _currentIndex,
onTap: (value) {
setState(() {
_currentIndex = value;
if (_currentIndex == 2) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => QRCodePage(user: widget.myUser),
));
}
});
},
backgroundColor: Pallete.lightPink,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home_rounded), label: "Home"),
BottomNavigationBarItem(
icon: Icon(Icons.people_outline_rounded), label: "Friends"),
BottomNavigationBarItem(
icon: Icon(Icons.qr_code_rounded), label: "QR Code"),
],
),
),
);
}
}
我期望当用户点击底部导航栏上的“Friends”项目时立即显示
ListView.builder
或当他点击“Home”项目时显示 Text("Home")
。
我尝试使用一个函数来检查索引,然后将一些布尔值分配给 true 或 false,并根据该值显示我想要的小部件,但我遇到了一个问题,我需要点击底部导航之外的内容当我点击该项目以显示小部件后,它不会立即显示,而是我需要点击屏幕上的其他位置。
谢谢大家提前的帮助
检查此示例并自行定制。
在
TestView
中称之为
MaterialApp:home
class TestView extends StatelessWidget {
const TestView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Test page"),
),
body: Center(
child: ElevatedButton(
child: const Text('showModalBottomSheet'),
onPressed: () {
showModalBottomSheet<void>(
//isScrollControlled: true, //If you want the model to be full height
context: context,
builder: (BuildContext context) {
return const NavigationExample();
},
);
},
),
),
);
}
}
这是带有
NavigationExample
的 ListView.builder
小部件。
class NavigationExample extends StatefulWidget {
const NavigationExample({super.key});
@override
State<NavigationExample> createState() => _NavigationExampleState();
}
class _NavigationExampleState extends State<NavigationExample> {
int currentPageIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: NavigationBar(
onDestinationSelected: (int index) {
setState(() {
currentPageIndex = index;
});
},
indicatorColor: Colors.amber[800],
selectedIndex: currentPageIndex,
destinations: const <Widget>[
NavigationDestination(
selectedIcon: Icon(Icons.home),
icon: Icon(Icons.home_outlined),
label: 'Home',
),
NavigationDestination(
icon: Icon(Icons.business),
label: 'Business',
),
NavigationDestination(
selectedIcon: Icon(Icons.school),
icon: Icon(Icons.school_outlined),
label: 'School',
),
],
),
body: <Widget>[
Container(
color: Colors.red,
alignment: Alignment.center,
child: const Text('Page 1'),
),
ListView.builder(
itemCount: 5,
itemBuilder: (context, i) {
return ListTile(
title: Text("Index $i Title"),
subtitle: Text("Index $i Subtitle"),
);
}),
Container(
color: Colors.blue,
alignment: Alignment.center,
child: const Text('Page 3'),
),
][currentPageIndex],
);
}
}