Skip to content

showModalBottomSheet does not move along with keyboard #71418

@preethishenoy

Description

@preethishenoy

Here is my simple flutter application with showModalBottomSheet, it contains a textfield and a button. When the text field is pressed keyboard pops up. But, modalbottomsheet does not move up along with the keyboard. Tried adding bottom viewInsets padding. Is there any other way to move modalbottomsheet along with the keyboard?

import 'package:flutter/material.dart';

`void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        resizeToAvoidBottomInset: false,
        body: HomeScreen(),
      ),
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.yellow[200],
      child: Center(
        child: RaisedButton(
          color: Colors.purple[100],
          child: Text('Button'),
          onPressed: () {
            showModalBottomSheet(
                context: context,
                builder: (BuildContext context) {
                  return MyBottomSheet();
                });
          },
        ),
      ),
    );
  }
}

class MyBottomSheet extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.pink[200],
        child: Column(
          children: [
            TextField(
              autofocus: true,
            ),
            RaisedButton(
              child: Text('Next'),
              onPressed: () {},
            ),
          ],
        ),
      ),
    );
  }
}

Activity

added
f: material designflutter/packages/flutter/material repository.
frameworkflutter/packages/flutter repository. See also f: labels.
on Nov 30, 2020
ZainUrRehmanKhan

ZainUrRehmanKhan commented on Dec 1, 2020

@ZainUrRehmanKhan
Contributor

Current Work Around:

showBottomSheet has a property isScrollControlled, make it true.

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

Remove Scaffold from MyBottomSheet and give your container a fixed height. Wrap your MyBottomSheet Container with Padding and use MediaQuery.of(context).viewInsets for padding.

class MyBottomSheet extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: MediaQuery.of(context).viewInsets,
      child: Container(
        height: 400,
        color: Colors.pink[200],
        child: Column(
          children: [
            TextField(
              autofocus: true,
            ),
            RaisedButton(
              child: Text('Next'),
              onPressed: () {},
            )
          ],
        ),
      ),
    );
  }
}
ZainUrRehmanKhan

ZainUrRehmanKhan commented on Dec 1, 2020

@ZainUrRehmanKhan
Contributor

@TahaTesser Please Review this issue, The BottomSheet should be automatically moved above on the Keyboard popup, if possible.

pedromassangocode

pedromassangocode commented on Dec 1, 2020

@pedromassangocode

Hi @preethishenoy
Can you please elaborate what do you exactly want? It is not clear for me.
Thank you

added
in triagePresently being triaged by the triage team
waiting for customer responseThe Flutter team cannot make further progress on this issue until the original reporter responds
on Dec 1, 2020
preethishenoy

preethishenoy commented on Dec 1, 2020

@preethishenoy
Author

Current Work Around:

showBottomSheet has a property isScrollControlled, make it true.

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

Remove Scaffold from MyBottomSheet and give your container a fixed height. Wrap your MyBottomSheet Container with Padding and use MediaQuery.of(context).viewInsets for padding.

class MyBottomSheet extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: MediaQuery.of(context).viewInsets,
      child: Container(
        height: 400,
        color: Colors.pink[200],
        child: Column(
          children: [
            TextField(
              autofocus: true,
            ),
            RaisedButton(
              child: Text('Next'),
              onPressed: () {},
            )
          ],
        ),
      ),
    );
  }
}

Thanks for your response.
I did try this and it works.I have a navigation controller also placed over the modal screen. I have placed a navigation to transition from screen 1 to screen 2.I am using this modal sheet to implement a basic login workflow. Here , screen 1 is my Phone number screen and screen 2 is the OTP screen. Once I have a navigation controller, This issue does come up. Here is the link to my sample code. Appreciate any workaround for this issue.
https://drive.google.com/file/d/1vcEM8ltzeCClVOcm9gjbevVYpt3czVKC/view?usp=sharing

removed
waiting for customer responseThe Flutter team cannot make further progress on this issue until the original reporter responds
on Dec 1, 2020
preethishenoy

preethishenoy commented on Dec 1, 2020

@preethishenoy
Author

Hi @preethishenoy
Can you please elaborate what do you exactly want? It is not clear for me.
Thank you

Sorry, I have elaborated my issue and also added a link to my sample code above.

pedromassangocode

pedromassangocode commented on Dec 2, 2020

@pedromassangocode

From what you have said and by running the code it is not clear to me what is the issue here.

gif

ZainUrRehmanKhan

ZainUrRehmanKhan commented on Dec 2, 2020

@ZainUrRehmanKhan
Contributor
import 'package:flutter/material.dart';

`void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        resizeToAvoidBottomInset: false,
        body: HomeScreen(),
      ),
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.yellow[200],
      child: Center(
        child: RaisedButton(
          color: Colors.purple[100],
          child: Text('Button'),
          onPressed: () {
            showModalBottomSheet(
                context: context,
                builder: (BuildContext context) {
                  return MyBottomSheet();
                });
          },
        ),
      ),
    );
  }
}
class MyBottomSheet extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 100,
      color: Colors.pink[200],
      child: Column(
        children: [
          TextField(
            autofocus: true,
          ),
          RaisedButton(
            child: Text('Next'),
            onPressed: () {},
          )
        ],
      ),
    );
  }
}

@pedromassangocode try the above code, the bottom sheet will be hidden behind the keyboard, we want the bottom sheet to move along the keyboard by default, so we can view it above the keyboard without adding isScrollable = true in showModalBottomSheet and wrapping Container in MyBottomSheet with padding like this.

class MyBottomSheet extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: MediaQuery.of(context).viewInsets,
      child: Container(
        height: 400,
        color: Colors.pink[200],
        child: Column(
          children: [
            TextField(
              autofocus: true,
            ),
            RaisedButton(
              child: Text('Next'),
              onPressed: () {},
            )
          ],
        ),
      ),
    );
  }
}
pedromassangocode

pedromassangocode commented on Dec 2, 2020

@pedromassangocode

Thanks, now it is clear what the issue is.

flutter doctor -v
[✓] Flutter (Channel master, 1.24.0-8.0.pre.406, on Mac OS X 10.15.7 19H2 darwin-x64, locale en)
    • Flutter version 1.24.0-8.0.pre.406 at /Users/pedromassango/dev/SDKs/flutter_master
    • Framework revision 60bdcf55fe (6 hours ago), 2020-12-01 21:24:21 -0800
    • Engine revision 20caf54969
    • Dart version 2.12.0 (build 2.12.0-76.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at /Users/pedromassango/Library/Android/sdk
    • Platform android-30, build-tools 30.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.1, Build version 12A7403
    • CocoaPods version 1.9.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)

[✓] IntelliJ IDEA Community Edition (version 2020.2.3)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 51.0.3
    • Dart plugin version 202.8070

[✓] VS Code (version 1.51.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.16.0

[✓] Connected device (4 available)
    • Android SDK built for x86 (mobile) • emulator-5554 • android-x86    • Android 10 (API 29) (emulator)
    • macOS (desktop)                    • macos         • darwin-x64     • Mac OS X 10.15.7 19H2 darwin-x64
    • Web Server (web)                   • web-server    • web-javascript • Flutter Tools
    • Chrome (web)                       • chrome        • web-javascript • Google Chrome 86.0.4240.198

• No issues found!

52 remaining items

g-apparence

g-apparence commented on Aug 18, 2023

@g-apparence

Another possibility for those who are stuck with this

1 - install the flutter_keyboard_visibility package
2 - listen for keyboard changes inside your modal content state
(Don't forget to dispose it).

@override
  void initState() {
    super.initState();
    var keyboardVisibilityController = KeyboardVisibilityController();
    keyboardSubscription = keyboardVisibilityController //
        .onChange
        .listen((bool visible) {
      Future.delayed(const Duration(milliseconds: 500), () => setState(() {}));
    });
  }

  @override
  void dispose() {
    keyboardSubscription.cancel();
    super.dispose();
  }

If you don't wait 500Ms it seems that the keyboard is not fully opened and the bottomInset will return 0.

Give your content a height (here it is 372).

  double get height => 372 + bottomPadding;

  double get bottomPadding => MediaQuery.of(context).viewInsets.bottom;

Now you can just use that bottomPadding in your modal content. This will correctly up your content according to the keyboard.
(Tested on Android and iOS).

PollyGlot

PollyGlot commented on Sep 18, 2023

@PollyGlot

I am afraid but the solution proposed above doesn't work for me, all my bottomSheets rest fixed. It was working good before 3.10, since then till now with 3.13.4 everything is blocked and I can't find any solutions for now

Washoo

Washoo commented on Oct 1, 2023

@Washoo

You need to specify the context for the builder, for example:

showModalBottomSheet(
        context: context,
        isScrollControlled: true, // Important
        builder: (context2) { // The context for the MediaQuery!
          return Container(
                     padding: EdgeInsets.only(
                      bottom: MediaQuery.of(context2).viewInsets.bottom, // Context2 here
                    ),
            child: Column(
              mainAxisSize: MainAxisSize.min, // Important
              children: [
                //
              ],
            ),
          );
        });

The MediaQuery takes the bottom padding of the builder, and it will push the modal when the keyboard opens. I am using the latest Flutter version (3.13.6), and it works.

I am afraid but the solution proposed above doesn't work for me, all my bottomSheets rest fixed. It was working good before 3.10, since then till now with 3.13.4 everything is blocked and I can't find any solutions for now

mafreud

mafreud commented on Nov 2, 2023

@mafreud

@Washoo Thanks. It works with 3.13.9.
@pedromassangocode I think the issue has been solved and it is time to close.

mafreud

mafreud commented on Nov 2, 2023

@mafreud
juequinterore

juequinterore commented on Dec 1, 2023

@juequinterore

Adding some info that could be useful.

In my case the issue started happening when we upgraded Flutter from 3.3.10 to 3.19.3.

The issue ended up being that, for preventing scaling the app text according to the phone settings, we were using this code:

MediaQuery(
            data: MediaQueryData.fromWindow(WidgetsBinding.instance.window)
                .copyWith(textScaleFactor: 1),
            child: ResponsiveLayoutWidget(child: child!),
          )

After changing that code into this new code:

MediaQuery(
            data: MediaQuery.of(context).copyWith(textScaleFactor: 1),
            child: ResponsiveLayoutWidget(child: child!),
          )

It was solved.

yunweneric

yunweneric commented on Dec 15, 2023

@yunweneric

Finally I got the solution to this issue!

Wrap the child of the bottom sheet with padding and add bottom padding

 builder: (context) => Padding(
        padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
        child: child,
      ),
  static baseBottomSheet({required BuildContext context, bool? enableDrag, bool? isDismissible, required Widget child}) {
    return showMaterialModalBottomSheet(
      backgroundColor: Theme.of(context).cardColor,
      context: context,
      builder: (context) => Padding(
        padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
        child: child,
      ),
      useRootNavigator: false,
      isDismissible: isDismissible ?? true,
      enableDrag: enableDrag ?? true,
    );
  }

Screen Utils

If you are using the flutter_screenutil package then add this line

ScreenUtilInit(
  useInheritedMediaQuery: true, // <----this line
)
A7medking1

A7medking1 commented on Jan 2, 2024

@A7medking1

If you're using flutter_screenutil pub then you need to apply useInheritedMediaQuery: true

ScreenUtilInit(

        useInheritedMediaQuery: true,

        ....

it's working for me

Thanks worked

andresteves

andresteves commented on Feb 26, 2025

@andresteves
showModalBottomSheet(
        barrierColor: Theme.of(context).appColours.surface.withAlpha(200),
        enableDrag: true,
        showDragHandle: true,
        context: context,
        backgroundColor: Theme.of(context).appColours.background,
        builder: (context) =>  SingleChildScrollView(
                padding: EdgeInsets.only(
                    bottom: MediaQuery.of(context).viewInsets.bottom),
                child: Column(
                  children: [
                    SizedBox(
                      width: double.infinity,
                      height: 180,
                      child:  childWidget,
                    ),
                  ],
                ),
              )
);

iOS works fine but on Android it still hides behind keyboard.
If isScrollControlled: Platform.isAndroid ? true : false then it fills whole screen.

Flutter version
Flutter (Channel stable, 3.27.1, on macOS 14.4.1 23E224 darwin-arm64, locale en-DE)

flutter-triage-bot

flutter-triage-bot commented on Feb 26, 2025

@flutter-triage-bot

This issue is missing a priority label. Please set a priority label when adding the triaged-design label.

added
P2Important issues not at the top of the work list
triaged-designTriaged by Design Languages team
on Mar 12, 2025
yubarajshrestha

yubarajshrestha commented on Apr 6, 2025

@yubarajshrestha

The solution is pretty straight forward. Update your widgets in following manner.

showModalBottomSheet(
          context: context,
          isScrollControlled: true, // important
          builder: (context) => const YourWidgetOrLayout(),
          useRootNavigator: true,
          useSafeArea: true,
);

Your YourWidgetOrLayout() should use the Column or ListView.

...
return Container(
          margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), // important
          Column(
                    mainAxisSize: MainAxisSize.min, // important
                    children: [
                              // all of your widgets.
                    ],
          )
);
...

or

...
return Container(
          margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), // important
          ListView(
                    shrinkWrap: true, // important
                    children: [
                              // all of your widgets.
                    ],
          )
);
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listf: material designflutter/packages/flutter/material repository.found in release: 3.3Found to occur in 3.3found in release: 3.7Found to occur in 3.7frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @lukeirvin@Hixie@Kodam-zz@andresteves@HansMuller

        Issue actions

          showModalBottomSheet does not move along with keyboard · Issue #71418 · flutter/flutter