I'm trying to replicate some functionality similar to Google Maps for my own Flutter application. Also map based, I'd like the user to be able to select a point of interest and have the option to navigate to said location.
When they hit 'navigate', I want a bottom sheet to appear in place (or on top of) the existing Bottom Navigation Bar that I have for tab-based navigation.
showModalBottomSheet()
does this, however it has a barrier which prevents the user from interacting with the parent view. I need it without the barrier.
showBottomSheet()
doesn't have the barrier but it also doesn't get placed on top of the Bottom Navigation Bar.
Is there some solution in order to have this functionality? I am thinking to add the Bottom Navigation Bar to a Container that will show/hide based on whether the user is navigating or not, but I feel it's quite a hacked solution and was hoping for something more elegant.
I've attached a couple of images below:
The solution I've found would be to wrap the Scaffold
widget containing your bottomNavigationBar
into another Scaffold
. The idea would be to display your modal inside the parent Scaffold
so it would be on top of the bottomNavigationBar
inside the child Scaffold
.
class _MyWidgetState extends State<MyWidget> {
bool _showModal = false;
final _scaffoldKey = GlobalKey<ScaffoldState>();
PersistentBottomSheetController _bottomSheetController;
void _showOrHide(bool show) {
_showModal = show;
if (_showModal) {
_bottomSheetController = _scaffoldKey.currentState.showBottomSheet(
(_) => Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width,
child: Text('This is a BottomSheet'),
),
backgroundColor: Colors.white,
);
} else {
if (_bottomSheetController != null) _bottomSheetController.close();
_bottomSheetController = null;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
body: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
],
),
body: Center(
child: ElevatedButton(
child: Text('Show/Hide Modal Bottom Sheet'),
onPressed: () => _showOrHide(!_showModal),
),
),
),
);
}
}
In this example I am keeping a reference to my parent ScaffoldState
through _scaffoldKey
so I can call my showBottomSheet
on the correct Scaffold
.
Screenshot: