How to Move bottomsheet along with keyboard which has textfield(autofocused is true)?
Asked Answered
P

27

265

I'm trying to make a bottomsheet that has a text field and autofocus is set to true so that the keyboard pops up. But, bottomsheet is overlapped by the keyboard. Is there a way to move bottomsheet above the keyboard?

Padding(
  padding:
      EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
  child: Column(children: <Widget>[
    TextField(
      autofocus: true,
      decoration: InputDecoration(hintText: 'Title'),
    ),
    TextField(
      decoration: InputDecoration(hintText: 'Details!'),
      keyboardType: TextInputType.multiline,
      maxLines: 4,
    ),
    TextField(
      decoration: InputDecoration(hintText: 'Additional details!'),
      keyboardType: TextInputType.multiline,
      maxLines: 4,
    ),]);
Pothouse answered 20/12, 2018 at 12:48 Comment(3)
There's also a few open issues on Github: main issue and another with a comment that offers an animated solution.Pessa
For me, it's fixed simply by adding a Padding element as the last child of Column and set its padding as padding: MediaQuery.of(context).viewInsetsDurance
@Durance thank you. you should put your comment to answer.Stalagmite
L
430
  • To fix this issue
  1. All you need is to use Keyboard padding using MediaQuery.of(context).viewInsets.bottom

  2. For more insurance, set isScrollControlled = true of the BottomSheetDialog this will allow the bottom sheet to take the full required height.

  • Note if your BottomSheetModel is Column make sure you add mainAxisSize: MainAxisSize.min otherwise the sheet will cover the whole screen.

  • Example

showModalBottomSheet(
        context: context,
        isScrollControlled: true,
        builder: (context) => Padding(
          padding: EdgeInsets.only(
                        bottom: MediaQuery.of(context).viewInsets.bottom),
          child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 12.0),
                    child: Text('Enter your address',
                        style: TextStyles.textBody2),
                  ),
                  SizedBox(
                    height: 8.0,
                  ),
                  TextField(
                      decoration: InputDecoration(
                        hintText: 'adddrss'
                      ),
                      autofocus: true,
                    ),                 
                ],
              ),
        ));
  • UPDATED

Flutter 2.2 breaks the changes again!” Now you need to give bottom padding once again so the keyboard doesn't overlap the bottomsheet.

Leath answered 15/8, 2019 at 20:39 Comment(11)
After applying this, the bottom sheet took up the whole screen. Worked around it through placing a static value for the height property of my Container widget for the bottom sheet.Oeflein
What is the child of the bottom sheet?Leath
@Leath I tried your method. Is it not working for my problem.. please check https://mcmap.net/q/110908/-how-to-push-all-content-up-when-open-keyboard/8822337Cadal
2021! you don't need it now: padding: MediaQuery.of(context).viewInsetsPenitence
new flutter lib dont need that, it will taking whole screenKindle
Adding "isScrollControlled = true" on showModalBottomSheet and "mainAxisSize: MainAxisSize.min" on Column widgets solved my all the issues. Thanks Abed.Syzran
Also make sure that the height of the builder widget isn't fixedNomism
How to add auto-scroll when an input gets focused in a scrollable modal?Nasser
Are these solutions still valid? this did not work for me. @LeathAgatha
Simple and efficient solutionCretan
Note that for flutter 3.1.0, if what is returned by the builder is a Container with height defined, the height of the bottom sheet will not update.Sufism
A
210

Just add:

  • isScrollControlled: true to showModalBottomSheet
  • padding: MediaQuery.of(context).viewInsets to widget in builder
  • column/wrap both works
showModalBottomSheet<void>(
  isScrollControlled: true,
  context: context,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.only(
        topLeft: Radius.circular(30.0),
        topRight: Radius.circular(30.0)),
  ),
  builder: (BuildContext context) {
    return Padding(
        padding: MediaQuery.of(context).viewInsets,
        child: Container(
            child: Wrap(
          children: <Widget>[
            TextField(
              decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: 'Enter a search term'),
            ),
            TextField(
              decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: 'Enter a search term'),
            ),
            TextField(
              decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: 'Enter a search term'),
            ),
            TextField(
              decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: 'Enter a search term'),
            )
          ],
        )));
  },
);

Update Feb 25 2020 better solution

showModalBottomSheet(
 isScrollControlled: true,
 builder: (BuildContext context) {

    return SingleChildScrollView(
      child: Container(
        padding:
            EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
        child: Padding(
          padding: const EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 0.0), // content padding
          child: Form(...)) // From with TextField inside


});
Aerophobia answered 23/11, 2019 at 8:26 Comment(1)
Just a note for everyone: For the question asked, Wrap widget is not required since the problem is about the bottomSheet being able to move above the keyboard and not the content of the bottom sheet it self.Obi
C
44

In Order to focus on the Keyboard in BottomSheet - Wrap TextField in Padding Widget as like Below e.g Code:

showModalBottomSheet(
              context: context,
              builder: (context) {
                return Container(
                  child: Padding(
                    padding: EdgeInsets.only(
                        bottom: MediaQuery.of(context).viewInsets.bottom),
                    child: TextField(
                      autofocus: true,
                    ),
                  ),
                );
              }); 
Chansoo answered 21/12, 2018 at 6:0 Comment(4)
Hi Thanks. This works for two child fields but not when we add a third field. I have edited question with my code sample.Pothouse
@ManjunathRao You probably need to add "Key" to textfield to keep them unique in order to get more than 2. Let me know if this helpedTamera
BottomSheet - has the maxHeight: constraints as the Fields are Increasing height won't increase. You can use ListView in BottomSheet to make fields visible in scroll. or you can try this - #53312053Chansoo
@ManjunathRao - you wont get more than two Fields in BottomSheet as such - Due to maxHeight: constraintsChansoo
W
25

In the latest version of flutter, you can move your bottomSheet using isScrollControlled property/named parameter. Suppose i have a function(_showModal) which will invoke when a button is pressed. And i define the bottom sheet functionality on that function.

void _showModal() {
  showModalBottomSheet(
    isScrollControlled: true,
    context: context,
    builder: (BuildContext context) {
      return Column(
        children: <Widget>[
          TextField(// your other code),
          SizedBox(height: 5.0),
          TextField(// your other code),
          SizedBox(height: 5.0),
          TextField(// your other code),
        ]
      );
    },
  );
}

Here a ModalBottomSheet will appear but with fullscreen of height. And you don't need that height. So, you need to Column's mainAxisSize to min.

Column(
  mainAxisSize: MainAxisSize.min,
  // your other code
)

Fullscreen of height problem is solved, but ModalBottomSheet doesn't move to top when keyboard is appeared. Ok, to solve this issue you need to set viewInsets bottom padding to your ModalBottomSheet. So to set padding we need to wrap our Column with Container or Padding and then set the padding. The final code will look like this

void _showModal() {
  showModalBottomSheet(
    isScrollControlled: true,
    context: context,
    builder: (BuildContext context) {
      return Container(
        padding: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
        ),
        // You can wrap this Column with Padding of 8.0 for better design
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            TextField(// your other code),
            SizedBox(height: 5.0),
            TextField(// your other code),
            SizedBox(height: 5.0),
            TextField(// your other code),
          ]
        ),
      );
    },
  );
}

Hope your issue is fixed. Thank's 🙏

Willodeanwilloughby answered 31/7, 2020 at 18:25 Comment(1)
Work like a charm...!🙏Cottony
O
24

Package: https://pub.dev/packages/modal_bottom_sheet

Wrap your widget into Padding and set padding like this ==>

padding: MediaQuery.of(context).viewInsets // viewInsets will decorate your screen

You can use showMaterialModalBottomSheet or showModalBottomSheet or showCupertinoModalBottomSheet

showModalBottomSheet(
        context: context,
        barrierColor: popupBackground,
        isScrollControlled: true, // only work on showModalBottomSheet function
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.only(
                topLeft: Radius.circular(borderRadiusMedium),
                topRight: Radius.circular(borderRadiusMedium))),
        builder: (context) =>  Padding(
            padding: MediaQuery.of(context).viewInsets,
            child: Container(
                   height: 400, //height or you can use Get.width-100 to set height
                   child: <Your Widget here>
             ),)),)

before

after

Oracle answered 5/8, 2021 at 4:43 Comment(2)
hi Can u please tell which Font have you used for your app ??Inductee
It's Ubuntu. You can download it from here -> fonts.google.com/specimen/UbuntuOracle
V
21

Try this

My Solution is

  • Use isScrollControlled: true
  • Add Padding
    padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom)
    
  • Wrap your layout in SingleChildScrollView

SAMPLE CODE

Future<void> future = showModalBottomSheet(
  context: context,
  isDismissible: true,
  isScrollControlled: true,
  backgroundColor: Colors.white.withOpacity(0.2),
  builder: (context) => SingleChildScrollView(
    child: GestureDetector(
      child: Padding(
        padding: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom
        ),
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          child: Column(
            children: <Widget>[
              // add your widget here
            ],
          ),
        ),
      )
    ),
  )
);
Viceregal answered 7/4, 2020 at 10:39 Comment(2)
the point of SingleChildScrollView wrapping is important. thanksJabin
This helped in maintaining the symmetry .. ThanksSubacid
A
13

I got it fixed by increasing the height of the child widget when the keyboard gets opened. initially value of MediaQuery.of(context).viewInsets.bottom will be 0 it will change when the keyboard gets focused.

showModalBottomSheet<void>(
      enableDrag: true,
      isScrollControlled: true,
      context: context,
      builder: (BuildContext context) {
        return Card(
          color: Colors.white,
          child: Container(
            height: MediaQuery.of(context).size.height / 2 +
                MediaQuery.of(context).viewInsets.bottom,
            child: Column(
              children: <Widget>[
                TextField(),
                TextField(),
              ],
            ),
          ),
        );
      },
    );
Andel answered 19/5, 2020 at 8:41 Comment(1)
That's the behavior I wanted! Congrats!Liberalism
F
13

For people who can't solve their problem trying all the answers. These answers are correct but not so clear.

When using

MediaQuery.of(context).viewInsets.bottom)

make sure your context variable is using the one provided by bottom sheet builder property.

builder :(**c**)=>MediaQuery.of(**c**)

Fichtean answered 2/1, 2021 at 1:37 Comment(1)
thanks, just change to my showModalBottomSheet context fix the problem.Midge
P
12

UPDATED 2021 May flutter 2.2! Now you need to give bottom padding. The below written was a bug.

UPDATED 2020!

This answer is true, but you don't have to give bottom padding now! Find and delete this line:

padding: MediaQuery.of(context).viewInsets

Penitence answered 23/3, 2021 at 15:47 Comment(2)
Thank you, Good hint. Your solution works for me (Flutter stable revision 60bd88df91). But checkout the ref a5262 (Revert "[showModalBottomSheet] fix: showModalBottomSheet does not move along keyboard") at github.com/flutter/flutter/commits/master/packages/flutter/lib/…. So I think we may need to track issue in the upcoming updates of Flutter.Usm
Confirmed, flutter 2.2 broke this again and you need the MediaQuery again.Ternopol
E
7

Add this after the last widget of your bottom sheet

Padding(padding: EdgeInsets.only(bottom:MediaQuery.of(context).viewInsets.bottom))
Eudiometer answered 12/12, 2021 at 21:25 Comment(0)
A
6

Try this.

showModalBottomSheet(
        isScrollControlled: true,
        context: context,
        builder: (context) {
          return AnimatedPadding(
              padding: MediaQuery.of(context).viewInsets,
              duration: const Duration(milliseconds: 100),
              curve: Curves.decelerate,
              child: Container(
                  child: Wrap(
                children: [
                  TextField(
                    decoration: InputDecoration(labelText: "1"),
                  ),
                  TextField(
                    decoration: InputDecoration(labelText: "2"),
                  ),
                  TextField(
                    decoration: InputDecoration(labelText: "3"),
                  ),
                ],
              )));
        },
      )
Adumbral answered 30/3, 2021 at 9:59 Comment(0)
B
6

You should to use this then,

showModalBottomSheet(
    isScrollControlled: true,
    context: context,
    shape: RoundedRectangleBorder(
      // <-- for border radius
      borderRadius: BorderRadius.only(
        topLeft: Radius.circular(10.0),
        topRight: Radius.circular(10.0),
      ),
    ),
    builder: (BuildContext context) {
      return SingleChildScrollView(
        padding:
            EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
        child: drunkenWidget()...

//BTW, Never ever Drink
Breastplate answered 20/5, 2021 at 14:15 Comment(0)
S
6
showModalBottomSheet(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(15.0),
      ),
      context: context,
      isScrollControlled: true,
      builder: (builder) {
        return Container(
          height: MediaQuery.of(context).size.height - 40,
          padding: MediaQuery.of(context).viewInsets,
          child: <Your Widget Here>,
        );
      },
    );

enter image description here

Suboceanic answered 12/3, 2022 at 13:28 Comment(0)
T
4

After combining different solutions I got this:

if you don't want it to be Full screen and don't want to use the Padding workaround use

  showModalBottomSheet(
      context: context,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      enableDrag: true,
      isDismissible: true,
      useRootNavigator: true,
      builder: (BuildContext ctx) {
        return Scaffold( // use CupertinoPageScaffold for iOS
          backgroundColor: Colors.transparent,
          resizeToAvoidBottomInset: true, // important
          body: SingleChildScrollView(
            child: Form(
              child: Container(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: <Widget>[
                    TextFormField(),
                    TextFormField(),
                  ],
                ),
              ),
            ),
          ),
        );
      },
    );

on Flutter (Channel master, v1.15.3-pre.37, on Mac OS X 10.15.2 19C57, locale en-US)

Thoria answered 14/2, 2020 at 10:46 Comment(0)
B
4

If you have full screen or fixed size showModalBottomSheet don't use padding it will not solve your problem. Use margin instead of padding like this :

  showModalBottomSheet(
          context: context,
          builder: (context) {
            return Container(
                marign: EdgeInsets.only(
                    bottom: MediaQuery.of(context).viewInsets.bottom),
                child: TextField()
            );
          }); 
Burgas answered 30/7, 2020 at 9:8 Comment(0)
C
4

Instead of using builder: (BuildContext context) { } in the builder, use builder: (context) { }

With this solution my modal bottom sheet sticks to the statusbar (acts like Scaffold with resizeToAvoidBottomInset: false) and allows to view all the form fields and scroll through the form if it is still needed to view bottom text fields.

For more details, here's the link from where I found the solution- https://github.com/flutter/flutter/issues/18564#issuecomment-602604778

Casie answered 2/11, 2020 at 7:25 Comment(0)
R
4

In my case it worked only when added this line to Scaffold inside the page who is calling showModalBottomSheet:

Scaffold(
  resizeToAvoidBottomInset: false,
  ..
),

And for sure, you need to add padding inside the showModalBottomSheet 's builder:

showModalBottomSheet(
  context: context,
  isScrollControlled: true,
  builder: (context) {
    return Container(
      padding: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
      ),
      child: Container(), // Your layout goes here..
    );
  }
);
Radiometer answered 26/2, 2023 at 13:17 Comment(1)
This no longer works for me in Flutter 3.3.10. Anything that would prevent this from working?Bitterweed
C
3

If you still have not found your issue. So I think you have missed in your BuilderContext. Sometimes when you implement modalBottomSheet it will give you only the context parameter. So add context with BuildContext.

 builder: (BuildContext context) {  //-Here is your issue add BuilderContext class name as it as 
          return Padding(
            padding: MediaQuery.of(context).viewInsets,
            child: SingleChildScrollView(
              child: Padding(
                padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
                child: new Container(
Crease answered 13/2, 2022 at 9:44 Comment(0)
U
2

Wrap the Form with a Scaffold widget, and then wrap the TextFormField with a SingleChildScrollView :


 return Container(
          height: screenHeight * .66,
          child: Scaffold(
             body: Form(
               key: _form,
               child: SingleChildScrollView(
                 child:TextFormField()
               )
              )
             )
           )
Unwise answered 17/8, 2019 at 2:11 Comment(1)
Scaffold(child:?Cadal
S
2

Fount this on github

Padding(
  padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
  child: TextField()
)
Sandstorm answered 6/12, 2020 at 8:43 Comment(0)
M
2

Add this in your router link modal bottom sheet

 showModalBottomSheet(              
     context: context,
     isScrollControlled: true,
      builder: (BuildContext context) {
      return Messagescr();
      }
    );

And remove this line also in your Scaffold :

resizeToAvoidBottomInset : false,
            
Muntin answered 17/9, 2022 at 21:57 Comment(0)
A
1
showModalBottomSheet(
 isScrollControlled: true,
 builder: (BuildContext context) {

    return SingleChildScrollView(
      child: Container(
        padding:
            EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
        child: Padding(
          padding: const EdgeInsets.all(15.0), // content padding
          child: Container())});

Note : This line does all the magic

Abdella answered 26/8, 2020 at 14:31 Comment(0)
H
1

Before trying any of the above solutions don't forget to add resizeToAvoidBottomInset: false to the parent Scaffold widget.

Hardaway answered 28/5, 2023 at 13:22 Comment(0)
D
1

all solutions are good. but for modals that have a fixed header and a long body with a text field in bottom I recommended this solution. that height is more than screen.height/2

 showMaterialModalBottomSheet<void>(
// isScrollControlled: true,

context: context,

backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
  // side: BorderSide(color: Colors.grey),
  borderRadius: BorderRadius.only(
      topLeft: Radius.circular(10),
      topRight: Radius.circular(10)),
),
builder: (BuildContext context) {
  return Padding(
  padding: MediaQuery.of(context).viewInsets,
  child: Container(
      height: height - MediaQuery.of(context).viewInsets.bottom,
      decoration: BoxDecoration(
        color: ColorConstants.background,
        borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10),
            topRight: Radius.circular(10)),
      ),
      padding:EdgeInsets.all(0),
      child: Wrap(
        children: [
       // fixed header
          Container(
            height: 56,
            alignment: Alignment.center,
            padding: EdgeInsets.all(8),
            decoration: BoxDecoration(
            
              borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(10),
                  topRight: Radius.circular(10)),
            ),
         
          ),
          SizedBox(
              height: height -
                  56 -
                  MediaQuery.of(context).viewInsets.bottom,
              child: (scrollable body with textfield))
        ],
      )));
    },
);
Dinnage answered 26/6, 2023 at 8:52 Comment(0)
M
0

import 'dart:async';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import '../weight/boostrap/flutter_bootstrap.dart';
import '../weight/boostrap/bootstrap_widgets.dart';

/*
  TextEditingController txtname = TextEditingController();
          showModalBottomSheet(
            context: context,
            isScrollControlled: true,
            shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(20),
                topRight: Radius.circular(20),
              ),
            ),
            builder: (context) => SingleChildScrollView(
              padding: EdgeInsets.only(
                  bottom: MediaQuery.of(context).padding.bottom),
              child: new AddItem(
                  tektk: 'Category',
                  tektd: 'Add',
                  txtname: txtname,
                  ismultik:false,
                  onPressed: () {}),
            ),
          );
    */
class AddItem extends StatelessWidget {
  const AddItem(
      {Key? key,
      required this.ismultik,
      required this.tektd,
      required this.tektk,
      required this.txtname,
      required this.onPressed})
      : super(key: key);
  final bool ismultik;
  final String tektk;
  final String tektd;
  final VoidCallback? onPressed;
  final TextEditingController txtname;
  @override
  Widget build(BuildContext context) {
    final MediaQueryData mediaQueryData = MediaQuery.of(context);
    bootstrapGridParameters(gutterSize: 10);
    return Padding(
      padding: mediaQueryData.viewInsets,
      child: Container(
        padding: EdgeInsets.only(bottom: 90.0, left: 10.0, right: 10.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            ListTile(
              trailing: SizedBox.fromSize(
                size: Size(35, 35),
                child: ClipOval(
                  child: Material(
                    color: Colors.indigo,
                    child: InkWell(
                      splashColor: Colors.white,
                      onTap: () {
                        Navigator.pop(context);
                      },
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Icon(Icons.close, color: Colors.white),
                        ],
                      ),
                    ),
                  ),
                ),
              ),
            ),
            BootstrapRow(height: 0, children: [
              BootstrapCol(
                sizes: 'col-md-12',
                child: TextField(
                  style: TextStyle(color: Colors.black),
                  decoration: new InputDecoration(
                    border: new OutlineInputBorder(
                        borderSide: new BorderSide(color: Colors.white)),
                    labelText: tektk,
                  ),
                  keyboardType: ismultik == true
                      ? TextInputType.multiline
                      : TextInputType.text,
                  maxLines: null,
                  minLines: 1,
                  controller: txtname,
                ),
              ),
              BootstrapCol(
                sizes: 'col-md-12',
                child: ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      primary: Colors.green, // background
                      onPrimary: Colors.white, // foreground
                    ),
                    onPressed: onPressed,
                    child: Text(tektd)),
              ),
            ]),
          ],
        ),
      ),
    );
  }
}
Marley answered 14/8, 2022 at 18:41 Comment(2)
you need to use comments to describe your codeMinny
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Hocuspocus
Y
0

Abed's answer stated the correct solution to your specific question. However, there are many other tricky issues to solve when creating a bottom sheet. Here is my complete working bottom sheet creator function, which will hopefully help someone.

import 'package:flutter/material.dart';

Future Function() openBottomSheet(BuildContext context, Widget child,
    {String? title}) {
  return () => showModalBottomSheet(
        // Don't let bottom sheet extend past the top of the safe area
        useSafeArea: true,
        context: context,
        // Round the top of the bottom sheet
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12.0),
        ),
        // Add scrollbar when necessary
        isScrollControlled: true,
        builder: (context) => ScrollableWidget(
          child: Container(
            // Move bottom sheet above on-screen keyboard, if keyboard is open
            padding: EdgeInsets.only(
                bottom: MediaQuery.of(context).viewInsets.bottom),
            child: Stack(
              children: [
                // Add back button at top left of bottom sheet (since it's
                // not obvious that sheet can be swiped down to close it)
                const BackButton(),
                Padding(
                  // Pad the main widget (larger padding on the top to leave
                  // space for the back button)
                  padding: const EdgeInsets.fromLTRB(20.0, 35.0, 20.0, 25.0),
                  child: Column(
                    children: [
                      // Make content full-width, so that main widget is
                      // centered even if it doesn't expand
                      Row(
                        mainAxisSize: MainAxisSize.max,
                        children: const [SizedBox(height: 0)],
                      ),
                      // Add title text to top of bottom sheet, if provided
                      title == null
                          ? Container()
                          : Column(
                              children: [
                                Text(
                                  title,
                                  style: const TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 18),
                                  textAlign: TextAlign.center,
                                ),
                                const SizedBox(height: 8),
                              ],
                            ),
                      // Add the main widget
                      child,
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      );
}

/// A scrollable widget with a scrollbar that is shown when necessary
class ScrollableWidget extends StatefulWidget {
  const ScrollableWidget({super.key, required this.child});

  final Widget child;

  @override
  State<ScrollableWidget> createState() => _ScrollableWidgetState();
}

class _ScrollableWidgetState extends State<ScrollableWidget> {
  final controller = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scrollbar(
      thumbVisibility: true,
      thickness: 15,
      radius: const Radius.circular(8),
      controller: controller,
      child: SingleChildScrollView(
        // Same controller must be used on Scrollbar and SingleChildScrollView
        controller: controller,
        child: widget.child,
      ),
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}
Yelena answered 22/2, 2023 at 23:30 Comment(0)
E
-2

Just add

if (_isEditing) SizedBox(height: MediaQuery.of(context).viewInsets.bottom),

under the keyboard and hide all other content below the textfield with

if (!_isEditing) Widget(...),
Explanation answered 9/7, 2021 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.