Flutter show Bottom Modal Sheet bove the Bottom Navigation Bar
Flutter show Bottom Modal Sheet bove the Bottom Navigation Bar
在下图中,我在单击“底部导航栏”项时添加了 showModalBottomSheet,但是 BottomNavigationBar 被模态 sheet 隐藏了,所以我想让它即使在底部也可见sheet 存在。谁能请任何人帮助我。
这是我的底部导航代码:
Widget _bottomNavigationBar() {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
key: scaffoldState,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.branding_watermark_outlined),
label: 'Brands',
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: 'Category',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
)
],
currentIndex: _selectedIndex,
selectedItemColor: AppColors.blue,
onTap: (newIndex) => {
if (newIndex == 1)
{showBrandsBottomSheet(context)}
else if (newIndex == 2)
{showCategoryBottomSheet(context)}
else
{
setState(() {
_selectedIndex = newIndex;
})
}
});
}
这是我的底层模型代码 sheet:
showBrandsBottomSheet(BuildContext context) {
return showModalBottomSheet<void>(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15.0), topRight: Radius.circular(15.0)),
),
context: context,
useRootNavigator: true,
isScrollControlled: true,
builder: (BuildContext _) {
return Container(
color: Colors.white,
height: MediaQuery.of(context).size.height / 2,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 5, top: 3),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Align(
alignment: Alignment.topRight,
child: Icon(Icons.close)),
),
),
Container(
color: Colors.white,
height: 350,
child: ListView.builder(
key: Key('builder ${_selected.toString()}'), //a
scrollDirection: Axis.vertical,
// shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
itemCount: brandList.length,
itemBuilder: (BuildContext context, int index) {
return Theme(
data: Theme.of(context)
.copyWith(dividerColor: Colors.white),
child: ExpansionTile(
// tilePadding: const EdgeInsets.all(0),
key: Key(index.toString()), //attention
initiallyExpanded: index == _selected, //attention
collapsedIconColor: Colors.blue,
iconColor: Colors.blue,
backgroundColor: Colors.white,
title: Text(
brandList[index],
style: const TextStyle(
fontSize: 13.0,
color: Colors.black,
fontWeight: FontWeight.w600),
),
children: <Widget>[
Container(
color: Colors.blue[50],
child: Column(
children: _buildExpandableBrands(brandList),
),
),
],
onExpansionChanged: ((newState) {
if (newState) {
setState(() {
const Duration(seconds: 20000);
_selected = index;
});
} else {
setState(() {
_selected = -1;
});
}
}),
));
},
),
),
],
),
),
);
},
);
}
设置 useRootNavigator=true.This 将在所有其他内容之上显示模型 sheet。
showModalBottomSheet(
context: context,
isScrollControlled: true,
useRootNavigator: true,
builder: (context) {
return BottomBarView(
);
});
最后, 帮助我完成了这项工作。
这是我的工作代码:
Widget _bottomNavigationBar() {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
key: scaffoldState,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.branding_watermark_outlined),
label: 'Brands',
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: 'Category',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
)
],
currentIndex: _selectedIndex,
selectedItemColor: AppColors.blue,
onTap: (newIndex) => {
if (newIndex == 1)
{
_scaffoldKey.currentState?.showBottomSheet((_) => Container(
child: showBrandsBottomSheet(),
))
}
else if (newIndex == 2)
{
{
_scaffoldKey.currentState?.showBottomSheet((_) => Container(
child: showCategoryBottomSheet(),
))
}
}
else
{
setState(() {
_selectedIndex = newIndex;
})
}
});
}
showBrandsBottomSheet:
showBrandsBottomSheet() {
return Container(
color: Colors.white,
height: MediaQuery.of(context).size.height / 2,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 5, top: 3),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Align(
alignment: Alignment.topRight, child: Icon(Icons.close)),
),
),
Container(
color: Colors.white,
height: 350,
child: ListView.builder(
key: UniqueKey(),
scrollDirection: Axis.vertical,
itemCount: brandList.length,
itemBuilder: (BuildContext context, int index) {
cardKeyList.add(GlobalKey(debugLabel: "index :$index"));
return Theme(
data: Theme.of(context)
.copyWith(dividerColor: Colors.white),
child: ExpansionTileCard(
key: cardKeyList[index],
initiallyExpanded: false,
title: Text(
brandList[index],
style: const TextStyle(
fontSize: 13.0,
color: Colors.black,
fontWeight: FontWeight.w600),
),
children: <Widget>[
Container(
color: Colors.blue[50],
child: Column(
children: _buildExpandableBrands(brandList),
),
),
],
onExpansionChanged: (value) {
if (value) {
Future.delayed(const Duration(milliseconds: 200),
() {
for (var i = 0; i < cardKeyList.length; i++) {
if (index != i) {
cardKeyList[i].currentState?.collapse();
}
}
});
}
},
));
},
),
),
],
),
),
);
}
现在开始显示在底部导航上方。
在下图中,我在单击“底部导航栏”项时添加了 showModalBottomSheet,但是 BottomNavigationBar 被模态 sheet 隐藏了,所以我想让它即使在底部也可见sheet 存在。谁能请任何人帮助我。
这是我的底部导航代码:
Widget _bottomNavigationBar() {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
key: scaffoldState,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.branding_watermark_outlined),
label: 'Brands',
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: 'Category',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
)
],
currentIndex: _selectedIndex,
selectedItemColor: AppColors.blue,
onTap: (newIndex) => {
if (newIndex == 1)
{showBrandsBottomSheet(context)}
else if (newIndex == 2)
{showCategoryBottomSheet(context)}
else
{
setState(() {
_selectedIndex = newIndex;
})
}
});
}
这是我的底层模型代码 sheet:
showBrandsBottomSheet(BuildContext context) {
return showModalBottomSheet<void>(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15.0), topRight: Radius.circular(15.0)),
),
context: context,
useRootNavigator: true,
isScrollControlled: true,
builder: (BuildContext _) {
return Container(
color: Colors.white,
height: MediaQuery.of(context).size.height / 2,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 5, top: 3),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Align(
alignment: Alignment.topRight,
child: Icon(Icons.close)),
),
),
Container(
color: Colors.white,
height: 350,
child: ListView.builder(
key: Key('builder ${_selected.toString()}'), //a
scrollDirection: Axis.vertical,
// shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
itemCount: brandList.length,
itemBuilder: (BuildContext context, int index) {
return Theme(
data: Theme.of(context)
.copyWith(dividerColor: Colors.white),
child: ExpansionTile(
// tilePadding: const EdgeInsets.all(0),
key: Key(index.toString()), //attention
initiallyExpanded: index == _selected, //attention
collapsedIconColor: Colors.blue,
iconColor: Colors.blue,
backgroundColor: Colors.white,
title: Text(
brandList[index],
style: const TextStyle(
fontSize: 13.0,
color: Colors.black,
fontWeight: FontWeight.w600),
),
children: <Widget>[
Container(
color: Colors.blue[50],
child: Column(
children: _buildExpandableBrands(brandList),
),
),
],
onExpansionChanged: ((newState) {
if (newState) {
setState(() {
const Duration(seconds: 20000);
_selected = index;
});
} else {
setState(() {
_selected = -1;
});
}
}),
));
},
),
),
],
),
),
);
},
);
}
设置 useRootNavigator=true.This 将在所有其他内容之上显示模型 sheet。
showModalBottomSheet(
context: context,
isScrollControlled: true,
useRootNavigator: true,
builder: (context) {
return BottomBarView(
);
});
最后,
这是我的工作代码:
Widget _bottomNavigationBar() {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
key: scaffoldState,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.branding_watermark_outlined),
label: 'Brands',
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: 'Category',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
)
],
currentIndex: _selectedIndex,
selectedItemColor: AppColors.blue,
onTap: (newIndex) => {
if (newIndex == 1)
{
_scaffoldKey.currentState?.showBottomSheet((_) => Container(
child: showBrandsBottomSheet(),
))
}
else if (newIndex == 2)
{
{
_scaffoldKey.currentState?.showBottomSheet((_) => Container(
child: showCategoryBottomSheet(),
))
}
}
else
{
setState(() {
_selectedIndex = newIndex;
})
}
});
}
showBrandsBottomSheet:
showBrandsBottomSheet() {
return Container(
color: Colors.white,
height: MediaQuery.of(context).size.height / 2,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 5, top: 3),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Align(
alignment: Alignment.topRight, child: Icon(Icons.close)),
),
),
Container(
color: Colors.white,
height: 350,
child: ListView.builder(
key: UniqueKey(),
scrollDirection: Axis.vertical,
itemCount: brandList.length,
itemBuilder: (BuildContext context, int index) {
cardKeyList.add(GlobalKey(debugLabel: "index :$index"));
return Theme(
data: Theme.of(context)
.copyWith(dividerColor: Colors.white),
child: ExpansionTileCard(
key: cardKeyList[index],
initiallyExpanded: false,
title: Text(
brandList[index],
style: const TextStyle(
fontSize: 13.0,
color: Colors.black,
fontWeight: FontWeight.w600),
),
children: <Widget>[
Container(
color: Colors.blue[50],
child: Column(
children: _buildExpandableBrands(brandList),
),
),
],
onExpansionChanged: (value) {
if (value) {
Future.delayed(const Duration(milliseconds: 200),
() {
for (var i = 0; i < cardKeyList.length; i++) {
if (index != i) {
cardKeyList[i].currentState?.collapse();
}
}
});
}
},
));
},
),
),
],
),
),
);
}
现在开始显示在底部导航上方。