Search code examples
formsflutterbottom-sheetsinglechildscrollview

when using SingleChildScrollView can't drag down botttom sheet


I've created an app with bottomsheet and listview builder.In the bottom, there is a text button when I drag it up bottom sheet must appear. There is a form in that bottom sheet. I wrap bottom sheet with SingleChildScrollView. But when I click TextFormField key board appear and I can scroll the bottom sheet. But I can't drag it down and close the bottom sheet. Even when I press back arrow in the phone to get rid of the key board.

import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  const Home({Key key}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  @override
  Widget build(BuildContext context) {
    var width = MediaQuery.of(context).size.width;
    return Scaffold(

        resizeToAvoidBottomInset: false,
        body: Stack(
                children: [
                  ListView.builder(
                      itemCount: 1,
                      itemBuilder: (context, index) {
                        return Card(
                          );
                      }),
                  Positioned(
                    bottom: 0,
                    child: GestureDetector(
                      onPanEnd: (details) {
                        if (details.velocity.pixelsPerSecond.dy < 10) {

                          //Bottom Sheet.................................................................................................................

                          showModalBottomSheet(
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.vertical(
                                    top: Radius.circular(25)),
                              ),
                              backgroundColor: Colors.green,
                              context: context,
                              builder: (context) {
                                return SingleChildScrollView(
                                  child: Container(
                                    padding: EdgeInsets.all(10),
                                    child: Form(
                                        child: Column(
                                          children: [
                                            Icon(Icons.arrow_drop_down),
                                            Text("Drag down to Close"),

                                            Container(
                                              color: Colors.red,
                                              child: Column(
                                                children: [
                                                  Row(
                                                    children: [
                                                      Expanded(
                                                        child: TextFormField(
                                                          decoration: InputDecoration(
                                                            labelText: "Current amount",
                                                          ),
                                                        ),
                                                      ),
                                                    ],
                                                  ),
                                                  Row(
                                                    children: [
                                                      Expanded(
                                                          child: TextButton(
                                                              onPressed: () {},
                                                              child: Text("Submit"))),
                                                    ],
                                                  ),
                                                ],
                                              ),
                                            ),
                                          ],
                                    )),
                                  ),
                                );
                              });
                          // Bottom Sheet Ends ......................................................................................................................................................
                        }
                      },
                      child: Container(
                        color: Colors.blue,
                        width: width,
                        padding: EdgeInsets.all(10),
                        child: Column(
                          children: [
                            Icon(Icons.arrow_drop_up),
                            Text("Drag up to Enter an Account"),
                          ],
                        ),
                      ),
                    ),
                  )
                ]),
        );
  }
}

Solution

  • This can be done in two steps:

    1. place a SingleChildScrollView inside the showModalBottomSheet's builder function.

    2. make sure to use these properties:

    showModalBottomSheet(
        enableDrag: true,
        isScrollControlled: true,
        // ...
    );
    

    Also, extracting the showModalBottomSheet function call into a separate method can make your code more readable, making the two comments redundant.

    Here is a complete example:

    Widget openModalBottomSheet() {
    
        Size size = MediaQuery.of(context).size;
        showModalBottomSheet(
    
            enableDrag: false,
            isDismissible: false,
            isScrollControlled: true,
    
            context: context,
            builder:(context)
            {
              return GestureDetector(
                behavior: HitTestBehavior.opaque,
    
                child: SingleChildScrollView(
                  child: Container(
                    padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom+10),
                    // height: size.height*0.6,
                    decoration: BoxDecoration(
                      color: Colors.white,
    
                    ),
                    child: Column(
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(25.0),
                          child: Container(
                            decoration: BoxDecoration(
                              //color: Colors.red,
                              borderRadius: BorderRadius.circular(20),
                            ),
    
                            height: size.height*0.5,
                            width: double.infinity,
                            child: Card(
                              elevation: 4,
                              child: Padding(
                                padding: const EdgeInsets.all(12.0),
                                child: Form(
                                  key: _formKey,
                                  child: Column(
                                    mainAxisAlignment: MainAxisAlignment.start,
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: [
    
    
                                      NameField(
    
                                        name:sectionname,
                                        controller: null,
                                        icon: Icons.person,
                                        hintText: "Please enter section name",
                                        text: "you not enter Smaster",
    
                                        onchanged: (value)
                                        {
                                          setState(() {
                                            Administrative.instance.SectionName=value;
                                          });
    
                                        },
    
    
                                      ),
                                      NameField(
    
                                        controller:null,
                                        name:smaster,
                                        icon: Icons.vpn_key_outlined,
                                        hintText: "Please enter Section Smaster",
                                        text: "your enter empty Smaster",
                                        onchanged: (value)
                                        {
                                          setState(() {
                                            Administrative.instance.Smaster=value;
                                          });
    
                                        },
    
    
                                      ),
                                    ],
                                  ),
                                ),
                              ),
    
                            ),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.only(left: 20.0,right: 20.0,top: 8.0,bottom: 8.0),
                          child: Container(
                            width: double.infinity,
                            height: 60,
                            child: FlatButton(
                              color: Colors.black,
                              onPressed: (){
                                if(!_formKey.currentState.validate()){
                                  return;
                                }
                                else
                                {
                                  _formKey.currentState.save();
                                  // signupauth.instance.addstudent();
                                  if(Administrative.instance.SectionName==null)
                                  {
                                    Administrative.instance.SectionName=sectionname;
                                  }
    
                                  else if(Administrative.instance.Smaster==null)
                                  {
                                    Administrative.instance.Smaster=smaster;
                                  }
                                  print("hello"+ids);
                                  FirebaseFirestore.instance
                                      .collection("Section")
                                      .doc(ids).update({
                                    "SectionName":Administrative.instance.SectionName,
                                    "Smaster":Administrative.instance.Smaster,
                                  });
                                  Fluttertoast.showToast(
                                      msg: "Section is added",
                                      toastLength: Toast.LENGTH_LONG,
                                      gravity: ToastGravity.CENTER,
                                      timeInSecForIosWeb: 1,
                                      backgroundColor: Colors.grey,
                                      textColor: Colors.white,
                                      fontSize: 16.0
    
                                  );
                                  Navigator.pop(context);
                                }
    
    
                              },
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10.0),
    
                              ),
                              child: Text("Save",style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.bold),),
                            ),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.only(left: 20.0,right: 20.0,top: 8.0,bottom: 8.0),
                          child: Container(
                            width: double.infinity,
                            height: 60,
                            child: FlatButton(
                              color: Colors.black,
                              onPressed: (){
                                Navigator.pop(context);
                              },
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10.0),
    
                              ),
                              child: Text("Cancel",style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.bold),),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              );
            }
        );
      }