Close modal bottom sheet programmatically in flutter

后端 未结 4 2031
迷失自我
迷失自我 2020-12-25 09:23

I am displaying a BottomSheet via showModalBottomSheet() and inside several widgets with a GestureDetector. I would like to see the BottomSheet clos

相关标签:
4条回答
  • 2020-12-25 10:05
    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),
        );
      }
    }
    

    0 讨论(0)
  • 2020-12-25 10:06

    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")
          ),
        ]),
      );
    });
    
    0 讨论(0)
  • 2020-12-25 10:14

    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


    Showing and Hiding 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:


    Showing and Hiding 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:

    0 讨论(0)
  • 2020-12-25 10:14

    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>
    )
    
    0 讨论(0)
提交回复
热议问题