Search code examples
flutterscrollflutter-layoutflutter-pageviewsinglechildscrollview

BottomSheet (DraggableScrollableSheet) with dynamic height when button is pressed


So basically I want to be able to change the visible height of the DraggableScrollableSheet when Button is pressed. Like an arrow that will allow the user to lift up & down specific height.

enter image description here

I have the following code so far:

return Scaffold(
  appBar: AppBar(),
  body: Stack(
    children: <Widget>[
      Placeholder(),
      DraggableScrollableSheet(
        minChildSize: .1,
        initialChildSize: .1,
        maxChildSize: .5,
        builder: (context, scrollController) {
          return Container(
            height: size.height / 2,
            decoration: BoxDecoration(
              color: Theme.of(context).primaryColor,
              borderRadius: BorderRadius.vertical(
                top: Radius.circular(20),
              ),
            ),
            child: SingleChildScrollView(
              controller: scrollController,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  IconButton(
                    icon: Icon(Icons.arrow_upward),
                    onPressed: () {
                      print('THIS IS WHERE I WANT TO OPEN THE SHEET');
                    },
                  ),
                  Container(
                    height: size.height / 2.75,
                    child: PageView(
                      controller: _pageController,
                      onPageChanged: (int page) {
                        setState(() {
                          currentIndex = page;
                        });
                      },
                      children: <Widget>[
                        Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[Text('Page 1')]),
                        Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[Text('Page 2')]),
                        Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[Text('Page 3')]),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          );
        },
      ),
    ],
  ),
);

I have tried scrollController.jumpTo() & scrollController.animateTo() but all they do is move the IconButton instead of the DraggableScrollableSheet.

                  IconButton(
                    icon: Icon(Icons.arrow_upward),
                    onPressed: () {
                      scrollController.jumpTo(20);
                      scrollController.animateTo(20, duration: null, curve: null);
                    },
                  ),

enter image description here enter image description here


Solution

  • I couldn't effectively achieve the main goal of pressing a button and opening the DraggableScrollableSheet but I managed to change the status of the arrow Icon when the sheet is completely dragged up thanks to NotificationListener, here's how I did it:

    NotificationListener<DraggableScrollableNotification>(
            onNotification: (notification) {
              if (notification.extent > 0.48) {
                dragUpDown = false;
              } else {
                dragUpDown = true;
              }
              return true;
            },
            child: DraggableScrollableSheet(
              minChildSize: .1,
              initialChildSize: .1,
              maxChildSize: .5,
              builder: (context, scrollController) {
                return Container(
                  height: size.height / 2,
                  decoration: BoxDecoration(
                    color: Theme.of(context).primaryColor,
                    borderRadius: BorderRadius.vertical(
                      top: Radius.circular(20),
                    ),
                  ),
                  child: SingleChildScrollView(
                    controller: scrollController,
                    child: Column(...