I am displaying a BottomSheet via showModalBottomSheet
and inside several widgets with a GestureDetector.
I would like to see the BottomSheet clos
class _FABState extends State<FAB> {
bool isOpen = false;
var bottomSheetController;
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () {
setState(() {
isOpen = !isOpen;
});
print('tapped on the bottom sheet');
if(isOpen) {
bottomSheetController = showBottomSheet(
backgroundColor: Colors.transparent,
context: context,
builder: (ctx) {
return ClipRRect(
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20),
),
child: Container(
height: 150,
color: Colors.black,
child: TextField()
),
);
});
bottomSheetController.closed.then((value) {
setState(() {
isOpen = !isOpen;
});
});
} else {
Navigator.of(context).pop();
setState(() {
isOpen = !isOpen;
});
}
},
child: isOpen?Icon(Icons.arrow_downward):Icon(Icons.arrow_upward),
);
}
}
I could not find out how to pass on an event caught by a GestureDetector. However, closing a ModalBottomSheet programmatically is done via
Navigator.pop(context);
So I just call that pop function inside the onTap callback function of the GestureDetector.
showModalBottomSheet<Null>(context: context, builder: (BuildContext context)
{
return new SingleChildScrollView(child:
new Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
new GestureDetector(onTap: () {
Navigator.pop(context);
doSomething();
}, child:
new Text("Item 1")
),
new GestureDetector(onTap: () {
Navigator.pop(context);
doSomething();
}, child:
new Text("Item 2")
),
]),
);
});
Generally there are 2 types of bottom sheet.
(I) showModalBottomSheet
// works like Dialog
, not a part of Scaffold
(II) showBottomSheet
// this is a part of Scaffold
showModalBottomSheet
This code shows bottom sheet, and hides it when tapping on the FlutterLogo
@override
void initState() {
super.initState();
Timer.run(() {
showModalBottomSheet(
context: context,
builder: (_) {
return GestureDetector(
onTap: () => Navigator.of(context).pop(), // closing showModalBottomSheet
child: FlutterLogo(size: 200),
);
},
);
});
}
Output:
showBottomSheet
This code shows a button, which will open and close the bottom sheet.
PersistentBottomSheetController _controller;
GlobalKey<ScaffoldState> _key = GlobalKey();
bool _open = false;
@override
Widget build(BuildContext context) {
return Scaffold(
key: _key,
body: Center(
child: RaisedButton(
onPressed: () {
if (!_open) {
_controller = _key.currentState.showBottomSheet(
(_) => SizedBox(
child: FlutterLogo(size: 200),
width: double.maxFinite,
),
);
} else {
_controller.close();
}
setState(() => _open = !_open);
},
child: Text(_open ? "Close" : "Open"),
),
),
);
}
Output:
The fix in our code was to wrap our bottom sheet widget like this. The buttons in the bottom sheet still worked:
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => Navigator.pop(context),
child: <existing bottom sheet widget>
)