How do you adjust the height and borderRadius of a BottomSheet in Flutter?

I'm probably missing something obvious here, but my BottomSheet only takes up the bottom half the screen, even though the widgets in it take up more space. So now there is scrolling behavior inside the BottomSheet. I'd like to be able to increase the BottomSheet so that the user doesn't have to scroll as much.

I also want to add a borderRadius to the top of my BottomSheet, so that it looks more "modal"-y or "tab"-like.

Code:

void _showBottomSheet(BuildContext context) {
    showModalBottomSheet<Null>(
      context: context,
      builder: (BuildContext context) {
        return _bottomSheetScreen; // defined earlier on
      },
    );
}

I've tried:

showModalBottomSheet<Null>(
  context: context,
  builder: (BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: _borderRadius,
      ),
      height: 1000.0,
      child: _bottomSheetScreen,
    );
  },
);

but it seems like that only affects the contents inside the BottomSheet, and does not customize the BottomSheet itself.


Default height for bottomSheet is half the screenSize

If you want your bottomSheet to EXPAND according to your content DYNAMICALLY

use below code

showModalBottomSheet<dynamic>(
isScrollControlled: true,
context: context,
builder: (BuildContext bc) {
  return Wrap(
      children: <Widget>[...]
  )
 }
)

This will automatically expand the bottomSheet according to content inside.

For adding a radius on top of bottomSheet return below code to `bottomSheet'

Container(
  child: Container(
    decoration: new BoxDecoration(
      color: forDialog ? Color(0xFF737373) : Colors.white,
      borderRadius: new BorderRadius.only(
            topLeft: const Radius.circular(25.0),
            topRight: const Radius.circular(25.0))),
      child: yourWidget(),
   ),
)

Complete code meeting both requirements

showModalBottomSheet<dynamic>(
isScrollControlled: true,
context: context,
builder: (BuildContext bc) {
  return Wrap(
      children: <Widget>[
          Container(
                 child: Container(
                  decoration: new BoxDecoration(
                    color: forDialog ? Color(0xFF737373) : Colors.white,
                    borderRadius: new BorderRadius.only(
                          topLeft: const Radius.circular(25.0),
                          topRight: const Radius.circular(25.0))),
                    child: yourWidget(),
                 ),
              )
      ]
   )
 }
)

It's possible this way

showModalBottomSheet(
  context: context,
  isScrollControlled: true,
  backgroundColor: Colors.transparent,
  builder: (context) => Container(
    height: MediaQuery.of(context).size.height * 0.75,
    decoration: new BoxDecoration(
      color: Colors.white,
      borderRadius: new BorderRadius.only(
        topLeft: const Radius.circular(25.0),
        topRight: const Radius.circular(25.0),
      ),
    ),
    child: Center(
      child: Text("Modal content goes here"),
    ),
  ),
);
  1. Set isScrollControlled: true and backgroundColor: Colors.transparent for the modal
  2. Provide a Container with required height: as root widget to modal builder
  3. Provide BoxDecoration with required borderRadius for the Container

Sample Screenshot


You can use a Column Inside a SingleChildScrollView to dynamically change the height of bottom sheet and also it gets scrollable once it exceeds the available max height, make sure the isScrollControlled is set to true, And for the border radius the shape property will help you add the borderRadius to the bottomsheet. here's a dartpad example for the same


  Future<void> _showBottomSheet() async {
    return showModalBottomSheet(
      isScrollControlled: true,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(13)),
      backgroundColor: Colors.white,
      context: context,
      builder: (context) => SingleChildScrollView(
          child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: List.generate(kBoxes, (index) => _squareBox(index)))),
    );
  }


No need to wrap anything. Only set:

  • isScrollControlled: true in showModalBottomSheet
  • shrinkWrap: true, in ListView

Here is the minimal general code:

import 'package:flutter/material.dart';

Future<Widget> show123(BuildContext context) {
  return showModalBottomSheet<dynamic>(
      useRootNavigator: true,
      isScrollControlled: true,
      context: context,
      builder: (BuildContext bc) {
        return ListView(
          shrinkWrap: true,
          children: [
            ListItem(),
            ListItem(),
            ListItem(),
          ],
        );
      });
}

You can get inspired by my case which depends on the number of AlbumRow dynamically. If the height reaches the maximum, you can get to the bottom by scrolling.

enter image description here enter image description here


import 'package:flutter/material.dart';

Future<Widget> showBottomSheet(BuildContext context) {
  return showModalBottomSheet<dynamic>(
      useRootNavigator: true,
      barrierColor: Colors.black.withOpacity(0.5),
      isScrollControlled: true,
      context: context,
      builder: (BuildContext bc) {
        return ConstrainedBox(
          constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.9),
          child: Container(
            decoration: new BoxDecoration(
                color: Colors.blue, borderRadius: new BorderRadius.only(topLeft: const Radius.circular(25.0), topRight: const Radius.circular(25.0))),
            child: ListView(
              shrinkWrap: true,
              children: [
                Padding(
                  padding: const EdgeInsets.fromLTRB(30, 30, 30, 45),
                  child: Text(
                    'Choose Album',
                    textAlign: TextAlign.center,
                  ),
                ),
                AlbumRow(title: 'For Weekends arta iretnairstnaisetn aistn aisetn'),
                AlbumRow(title: 'Creative'),
                AlbumRow(title: 'Christmas'),
                AlbumRow(title: 'For Weekends arta iretnairstnaisetn aistn aisetn'),
              ],
            ),
          ),
        );
      });
}

Use showBottomSheet instead of showModalBottomSheet

Create global key and a listener

final _scaffoldKey = new GlobalKey<ScaffoldState>();
VoidCallback _showPersBottomSheetCallBack;

Write your method to show the sheet

  void _showBottomSheet() {
    setState(() {
      _showPersBottomSheetCallBack = null;
    });

    _scaffoldKey.currentState
        .showBottomSheet((context) {
      return new Container(
        height: MediaQuery.of(context).size.height-100.0,
        color: Colors.greenAccent,
        child: new Center(
          child: new Text("Hi BottomSheet"),
        ),
      );
    })
        .closed
        .whenComplete(() {
      if (mounted) {
        setState(() {
          _showPersBottomSheetCallBack = _showBottomSheet;
        });
      }
    });
  }

initialize the listener

void initState() {
    super.initState();
    _showPersBottomSheetCallBack = _showBottomSheet;
  }

Call the method wherever you required

new RaisedButton(
                  onPressed: _showPersBottomSheetCallBack,
                  child: new Text("Persistent"),
                ),

Hope it helps !