Getting to know Flutter: Advanced use of ModalBottomSheet
Tags: flutter, beginners, dart, tutorial
Published: 2021-09-29 15:03:28

Do you want to present a simple modal picker to the user or just show a nice feedback to a user action? In this tutorial you will learn how to use the [showModalBottomSheet](https://api.flutter.dev/flutter/material/showModalBottomSheet.html) function.

Let's start by creating a simple bottom sheet,  with a text and a button. As you can see to close a modal bottom sheet you will use the `.pop()` function of the Navigator, as you do when closing `Scaffold` Widgets.

```dart
class ModalBottomSheetsPage extends StatelessWidget {
  ModalBottomSheetsPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Modal bottom sheets'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Show modal bottom sheet'),
          onPressed: () => _showBottomSheet(context),
        ),
      ),
    );
  }

  void _showBottomSheet(BuildContext context) {
    showModalBottomSheet(
      context: context,
      builder: (context) => SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 20.0),
          child: Container(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Text(
                  'This is a Modal bottom sheet!',
                  style: Theme.of(context).textTheme.headline4,
                  textAlign: TextAlign.center,
                ),
                ElevatedButton(
                  child: const Text('Close BottomSheet'),
                  onPressed: () => Navigator.pop(context),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}
```
Let's add some fanciness and sound the top corners of our bottom sheet, this is incredibly easy, you just need to add the `shape` parameter to the `showModalBottomSheet` function, specifying the shape that we want to use.

``` dart
    showModalBottomSheet(
      context: context,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(15)),
      ),
      builder: (context) => SafeArea(
```

Now we will do a more complex example, we will display in the bottom sheet a list of 100 elements, and the sheet will expand/collapse while the user scrolls through the list. To do so we will use the [DraggableScrollableSheet](https://api.flutter.dev/flutter/widgets/DraggableScrollableSheet-class.html) widget.  
This widget has been created to do this types of sheet, it has a builder function that exposes a `ScrollController` that we will need to use in our ListView to keep the scrolling of the list in sync with the state of the bottom sheet.

In this case we're also passing the index of the list tile pressed in the pop function, so we could use it later. It will be the result of the `Future` of the `showModalBottomSheet` function, and we're retrieving it awaiting on`showModalBottomSheet`.

``` dart
  Future<void> _showBottomSheet(BuildContext context) async {
    int? result = await showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      isDismissible: true,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(15)),
      ),
      builder: (context) => DraggableScrollableSheet(
        initialChildSize: 0.4,
        minChildSize: 0.2,
        maxChildSize: 0.9,
        expand: false,
        builder: (context, scrollController) => SafeArea(
          child: ListView.builder(
            controller: scrollController,
            itemCount: 100,
            itemBuilder: (context, index) => ListTile(
              title: Text(index.toString()),
              onTap: () => Navigator.of(context).pop(index),
            ),
          ),
        ),
      ),
    );

    print(result);
  }
```