flutterbottom-sheet

Expanded widget takes full height of the screen irrespective of its children


I am using a dynamic bottom sheet with a column as its child. The last child of this column is a grid view. For some small screen devices, the content of this bottom sheet my get overflow so I wrapped the grid view inside an expanded widget. Now its content are scrollable if they are overflowing.

But the problem here is, even if the contents of the grid view are not overflowing (screen size is big enough) it still expands to full screen leaving empty space at the bottom. I am trying to solve this issue for past 3 days but no result. I tried various combinations of parent and child widget but nothing gives the satisfying result.

The result I am expecting is that the grid view should scroll when contents are overflowing and if not then it should take only the required space and not the entire screen.

Here is my entire code, the grid view with the problem is at the end :

showModalBottomSheet<dynamic>(
      isScrollControlled: true,
      context: context,
      builder: (BuildContext context) {
        return StatefulBuilder(
            builder: (context, setState) {
              return Container(
                color: Colors.white,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      width: double.infinity,
                      decoration: BoxDecoration(
                        border: Border(
                          bottom: BorderSide(color: Color.fromARGB(255, 225, 225, 225)),
                        ),
                        //color: Color.fromARGB(255, 255, 255, 255),
                      ),
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Padding(
                            padding: const EdgeInsets.fromLTRB(15, 15, 10, 15),
                            child: Icon(
                              Icons.save,
                              color: Color.fromARGB(255, 2, 136, 209),
                              size: 28.0,
                            ),
                          ),
                          Expanded(
                            child: Material(
                              color: Colors.transparent,
                              child: InkWell(
                                onTap: (){},
                                child: Padding(
                                  padding: const EdgeInsets.fromLTRB(8.0, 13.0, 10.0, 10.0),
                                  child: Column(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: [
                                      Row(
                                        mainAxisSize: MainAxisSize.min,
                                        crossAxisAlignment: CrossAxisAlignment.start,
                                        children: [
                                          Container(
                                            constraints: BoxConstraints(minWidth: 0, maxWidth: MediaQuery.of(context).size.width*(2/3)),
                                            child: Text(
                                              'PDF Name',
                                              overflow: TextOverflow.ellipsis,
                                              maxLines: 2,
                                              softWrap: true,
                                              style: TextStyle(
                                                fontSize: 16.0,
                                                fontWeight: FontWeight.bold,
                                                color: Color.fromARGB(255, 117, 117, 117),
                                              ),
                                            ),
                                          ),
                                          Padding(
                                            padding: EdgeInsets.fromLTRB(5.0, 0.0, 0.0, 0.0),
                                            child: Icon(
                                              Icons.edit,
                                              color: Color.fromARGB(255, 2, 136, 209),
                                              size: 16.0,
                                            ),
                                          ),
                                        ],
                                      ),
                                      Padding(
                                        padding: const EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 0.0),
                                        child: Text(
                                          "PDF Size",
                                          style: TextStyle(
                                            fontSize: 12.0,
                                            color: Color.fromARGB(255, 117, 117, 117),
                                          ),
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                    Row(
                        children: <Widget>[
                          Expanded(
                              child: Padding(
                                padding: const EdgeInsets.fromLTRB(0, 10, 0, 4),
                                child: Divider(
                                  color: Color.fromARGB(255, 220, 220, 220),
                                  thickness: 1.1,
                                ),
                              )
                          ),
                          Padding(
                            padding: const EdgeInsets.fromLTRB(10, 10, 10, 4),
                            child: Text(
                              "Share/Save File to",
                              style: TextStyle(
                                color: Color.fromARGB(255, 117, 117, 117),
                                fontSize: 15.0,
                              ),
                            ),
                          ),
                          Expanded(
                              child: Padding(
                                padding: const EdgeInsets.fromLTRB(0, 10, 0, 4),
                                child: Divider(
                                  color: Color.fromARGB(255, 220, 220, 220),
                                  thickness: 1.1,
                                ),
                              )
                          ),
                        ]
                    ),
                    Expanded(
                      child: GridView.count(
                        padding: EdgeInsets.fromLTRB(0, 0, 0, 15),
                        crossAxisCount: 3,
                        shrinkWrap: true,
                        childAspectRatio: 1.25,
                        children: <Widget>[
                          FileSaveCard(icon: Icons.phone_android, color: Colors.pink, title: 'Internal Storage', press: (){}),
                          FileSaveCard(icon: Icons.folder, color: Colors.blueAccent, title: 'My Documents', press: (){}),
                          FileSaveCard(icon: Icons.add_to_drive_rounded, color: Color.fromARGB(255, 254, 150, 0), title: 'Google Drive', press: (){}),
                          FileSaveCard(icon: Icons.mail, color: Colors.lightBlue, title: 'Send to Email', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                        ],
                      ),
                    ),
                  ],
                ),
              );
            }
        );
      },
    );

Here is the output image:

enter image description here

It even slides under that phone's status bar at the top. How can I avoid that as well.

This is the result I am expecting:

Case 1: When it is overflowing, this works fine as I have wrapped grid view in an expanded widget, it becomes scrollable -

enter image description here

Case 2: When screen size is sufficient for the children, below image should be the output, but I get empty space at bottom instead-

enter image description here

Okay, I figured it out finally. For the Status Bar overlapping part giving safe area and all was not working and as suggested by Sagar Acharya using FractionallySizedBox did prevented it but it forced the bottom sheet to take up full screen irrespective of its content height leaving empty space after its last item. Instead I used constraints: BoxConstraints(maxHeight: (MediaQuery.of(context).size.height)*0.95) which did not force sheet to take full height and also prevented it from overlapping status bar.

For the other problem I first removed expanded from top of my grid view and wrapped my whole column (containing all items of the bottom sheet) with SingleChildScrollView. Now it keeps the content wrapped until sheet reaches full screen height and when it does it becomes scrollable.

But still there is one thing I want to change, in my output my whole content of the bottom sheet is scrollable but I just want the grid view children to be scrollable, the top most 'PDF Name' and 'Share/Save File to' should not scroll along with it. Any ideas how I can do that. I tried using SingleChildScrollView on grid view instead of Column but it did not work (the element overflowed when the sheet reached full height)

Here is my code:

showModalBottomSheet<dynamic>(
      isScrollControlled: true,
      context: context,
      builder: (BuildContext context) {
        return StatefulBuilder(
            builder: (context, setState) {
              return Container(
                //height: 900,
                constraints: BoxConstraints(maxHeight: (MediaQuery.of(context).size.height)*0.95),
                color: Colors.white,
                child: SingleChildScrollView(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Container(
                        width: double.infinity,
                        decoration: BoxDecoration(
                          border: Border(
                            bottom: BorderSide(color: Color.fromARGB(255, 225, 225, 225)),
                          ),
                          //color: Color.fromARGB(255, 255, 255, 255),
                        ),
                        child: Row(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Padding(
                              padding: const EdgeInsets.fromLTRB(15, 15, 10, 15),
                              child: Icon(
                                Icons.save,
                                color: Color.fromARGB(255, 2, 136, 209),
                                size: 28.0,
                              ),
                            ),
                            Expanded(
                              child: Material(
                                color: Colors.transparent,
                                child: InkWell(
                                  onTap: (){},
                                  child: Padding(
                                    padding: const EdgeInsets.fromLTRB(8.0, 13.0, 10.0, 10.0),
                                    child: Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        Row(
                                          mainAxisSize: MainAxisSize.min,
                                          crossAxisAlignment: CrossAxisAlignment.start,
                                          children: [
                                            Container(
                                              constraints: BoxConstraints(minWidth: 0, maxWidth: MediaQuery.of(context).size.width*(2/3)),
                                              child: Text(
                                                'PDF Name',
                                                overflow: TextOverflow.ellipsis,
                                                maxLines: 2,
                                                softWrap: true,
                                                style: TextStyle(
                                                  fontSize: 16.0,
                                                  fontWeight: FontWeight.bold,
                                                  color: Color.fromARGB(255, 117, 117, 117),
                                                ),
                                              ),
                                            ),
                                            Padding(
                                              padding: EdgeInsets.fromLTRB(5.0, 0.0, 0.0, 0.0),
                                              child: Icon(
                                                Icons.edit,
                                                color: Color.fromARGB(255, 2, 136, 209),
                                                size: 16.0,
                                              ),
                                            ),
                                          ],
                                        ),
                                        Padding(
                                          padding: const EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 0.0),
                                          child: Text(
                                            "PDF Size",
                                            style: TextStyle(
                                              fontSize: 12.0,
                                              color: Color.fromARGB(255, 117, 117, 117),
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                      Row(
                          children: <Widget>[
                            Expanded(
                                child: Padding(
                                  padding: const EdgeInsets.fromLTRB(0, 10, 0, 4),
                                  child: Divider(
                                    color: Color.fromARGB(255, 220, 220, 220),
                                    thickness: 1.1,
                                  ),
                                )
                            ),
                            Padding(
                              padding: const EdgeInsets.fromLTRB(10, 10, 10, 4),
                              child: Text(
                                "Share/Save File to",
                                style: TextStyle(
                                  color: Color.fromARGB(255, 117, 117, 117),
                                  fontSize: 15.0,
                                ),
                              ),
                            ),
                            Expanded(
                                child: Padding(
                                  padding: const EdgeInsets.fromLTRB(0, 10, 0, 4),
                                  child: Divider(
                                    color: Color.fromARGB(255, 220, 220, 220),
                                    thickness: 1.1,
                                  ),
                                )
                            ),
                          ]
                      ),
                      GridView.count(
                        padding: EdgeInsets.fromLTRB(0, 0, 0, 15),
                        crossAxisCount: 3,
                        shrinkWrap: true,
                        //physics: NeverScrollableScrollPhysics(),
                        physics: const ScrollPhysics(),
                        childAspectRatio: 1.25,
                        children: <Widget>[
                          FileSaveCard(icon: Icons.phone_android, color: Colors.pink, title: 'Internal Storage', press: (){}),
                          FileSaveCard(icon: Icons.folder, color: Colors.blueAccent, title: 'My Documents', press: (){}),
                          FileSaveCard(icon: Icons.add_to_drive_rounded, color: Color.fromARGB(255, 254, 150, 0), title: 'Google Drive', press: (){}),
                          FileSaveCard(icon: Icons.mail, color: Colors.lightBlue, title: 'Send to Email', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),

                          /*FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                          FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),*/
                        ],
                      ),
                    ],
                  ),
                ),
              );
            }
        );
      },
    );

Any help would me much appreciated. Thank you.


Solution

    1. I think this is the answer you wanted
    import 'package:flutter/material.dart';
    import 'package:test11111/test1.dart';
    import 'package:get/get.dart';
    
    
    
    class MyStatelessWidget extends StatelessWidget {
      const MyStatelessWidget({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Center(
          child: ElevatedButton(
            child: const Text('showModalBottomSheet'),
            onPressed: () {
              showModalBottomSheet<void>(
                context: context,
                builder: (BuildContext context) {
                  return SingleChildScrollView(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Container(
                          height: Get.height* 0.4,
                          color: Colors.white,
                          child: Column(
                            children: [
                              Container(
                                width: double.infinity,
                                decoration: BoxDecoration(
                                  border: Border(
                                    bottom: BorderSide(color: Color.fromARGB(255, 225, 225, 225)),
                                  ),
                                ),
                                child: Row(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Padding(
                                      padding: const EdgeInsets.fromLTRB(15, 15, 10, 15),
                                      child: Icon(
                                        Icons.save,
                                        color: Color.fromARGB(255, 2, 136, 209),
                                        size: 28.0,
                                      ),
                                    ),
                                    Expanded(
                                      child: Material(
                                        color: Colors.transparent,
                                        child: InkWell(
                                          onTap: (){},
                                          child: Padding(
                                            padding: const EdgeInsets.fromLTRB(8.0, 13.0, 10.0, 10.0),
                                            child: Column(
                                              crossAxisAlignment: CrossAxisAlignment.start,
                                              children: [
                                                Row(
                                                  mainAxisSize: MainAxisSize.min,
                                                  crossAxisAlignment: CrossAxisAlignment.start,
                                                  children: [
                                                    Container(
                                                      constraints: BoxConstraints(minWidth: 0, maxWidth: MediaQuery.of(context).size.width*(2/3)),
                                                      child: Text(
                                                        'PDF Name',
                                                        overflow: TextOverflow.ellipsis,
                                                        maxLines: 2,
                                                        softWrap: true,
                                                        style: TextStyle(
                                                          fontSize: 16.0,
                                                          fontWeight: FontWeight.bold,
                                                          color: Color.fromARGB(255, 117, 117, 117),
                                                        ),
                                                      ),
                                                    ),
                                                    Padding(
                                                      padding: EdgeInsets.fromLTRB(5.0, 0.0, 0.0, 0.0),
                                                      child: Icon(
                                                        Icons.edit,
                                                        color: Color.fromARGB(255, 2, 136, 209),
                                                        size: 16.0,
                                                      ),
                                                    ),
                                                  ],
                                                ),
                                                Padding(
                                                  padding: const EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 0.0),
                                                  child: Text(
                                                    "PDF Size",
                                                    style: TextStyle(
                                                      fontSize: 12.0,
                                                      color: Color.fromARGB(255, 117, 117, 117),
                                                    ),
                                                  ),
                                                ),
                                              ],
                                            ),
                                          ),
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                              Row(
                                  children: <Widget>[
                                    Expanded(
                                        child: Padding(
                                          padding: const EdgeInsets.fromLTRB(0, 10, 0, 4),
                                          child: Divider(
                                            color: Color.fromARGB(255, 220, 220, 220),
                                            thickness: 1.1,
                                          ),
                                        )
                                    ),
                                    Padding(
                                      padding: const EdgeInsets.fromLTRB(10, 10, 10, 4),
                                      child: Text(
                                        "Share/Save File to",
                                        style: TextStyle(
                                          color: Color.fromARGB(255, 117, 117, 117),
                                          fontSize: 15.0,
                                        ),
                                      ),
                                    ),
                                    Expanded(
                                        child: Padding(
                                          padding: const EdgeInsets.fromLTRB(0, 10, 0, 4),
                                          child: Divider(
                                            color: Color.fromARGB(255, 220, 220, 220),
                                            thickness: 1.1,
                                          ),
                                        )
                                    ),
                                  ]
                              ),
                              Expanded(
                                child: GridView.count(
                                  padding: EdgeInsets.fromLTRB(0, 0, 0, 15),
                                  crossAxisCount: 3,
                                  shrinkWrap: true,
                                  childAspectRatio: 1.25,
                                  children: <Widget>[
                                    FileSaveCard(icon: Icons.phone_android, color: Colors.pink, title: 'Internal Storage', press: (){}),
                                    FileSaveCard(icon: Icons.folder, color: Colors.blueAccent, title: 'My Documents', press: (){}),
                                    FileSaveCard(icon: Icons.add_to_drive_rounded, color: Color.fromARGB(255, 254, 150, 0), title: 'Google Drive', press: (){}),
                                    FileSaveCard(icon: Icons.mail, color: Colors.lightBlue, title: 'Send to Email', press: (){}),
                                    FileSaveCard(icon: Icons.share, color: Colors.green, title: 'Share', press: (){}),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  );
                },
              );
            },
          ),
        );
      }
    }
    
    
    class FileSaveCard extends StatelessWidget {
      FileSaveCard(
          {Key? key,
          required this.icon,
          required this.color,
          required this.title,
          required this.press})
          : super(key: key);
      IconData icon;
      Color color;
      String title;
      VoidCallback press;
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Column(
            children: [
              IconButton(icon: Icon(icon), color: color, onPressed: press),
              Text(title)
            ],
          ),
        );
      }
    }
    

    enter image description here