66

NOTE: Im using Navigator.of(context).push to push ModalRoute,

Hi I have page with ModalRoute with TextFormField in the body, but when keyboard show up, the input is being hide by keyboard, how to fix this?

enter image description here

return Container(
      child: ListView(
          children: <Widget>[
            //other widget
            SizedBox(height: _qtyAnimation.value),
            Row(
              children: <Widget>[
                Expanded(
                  child: Text(
                    "Jumlah",
                    style: TextStyle(fontWeight: FontWeight.bold),
                  ),
                ),
                SizedBox(
                  width: 145.0,
                  child: TextFormField(
                    focusNode: _qtyFocusNode,
                    controller: qty,
                    keyboardType: TextInputType.number,
                    textAlign: TextAlign.center,
                    decoration: InputDecoration(
                      contentPadding: EdgeInsets.all(0.0),
                      prefixIcon: IconButton(
                        icon: Icon(Icons.remove),
                        onPressed: () {},
                      ),
                      border: OutlineInputBorder(
                        borderSide:
                            BorderSide(color: Colors.grey, width: 0.1),
                      ),
                      suffixIcon: IconButton(
                        icon: Icon(Icons.add),
                        onPressed: () {},
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ],
    );

thats my code, i try with focusnode and more, still same result please help me

Akshay Paliwal
  • 3,718
  • 2
  • 39
  • 43
RIFAL
  • 3,207
  • 4
  • 17
  • 29
  • You can use FocusNode to do that: https://stackoverflow.com/questions/50736571/when-i-select-a-textfield-the-keyboard-moves-over-it – Blasanka Dec 03 '18 at 05:43
  • Possible duplicate of [How to hide on screen keyboard?](https://stackoverflow.com/questions/50736571/when-i-select-a-textfield-the-keyboard-moves-over-it) – Blasanka Dec 03 '18 at 05:44
  • its not work for me, already test that link, – RIFAL Dec 03 '18 at 08:02
  • My solution [here at this thread](https://stackoverflow.com/a/68857184/8138591) solves this problem. It's very short and simple, no animation required. – Son Nguyen Aug 20 '21 at 05:10

14 Answers14

90

thanks solve my problem with this padding on bottom of textfield

    Padding(
             padding: EdgeInsets.only(
             bottom: MediaQuery.of(context).viewInsets.bottom));

and mare reverse list

Mahesh Jamdade
  • 17,235
  • 8
  • 110
  • 131
RIFAL
  • 3,207
  • 4
  • 17
  • 29
67

This worked for me...

First add this

final bottom = MediaQuery.of(context).viewInsets.bottom;

Then use a SingleChildScrollView() to wrap around the main widget (whatever you're using, e.g. Column, ListView, etc) like this...

You need "reverse: true"

Widget build{
return Scaffold(
body: SingleChildScrollView(
reverse: true;
child: Container(...

You also need these two lines of code for the Scaffold as well..

return Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,
body: SingleChildScrollView(...

and finally, reference the 'bottom' for your EdgeInsets..

body: SingleChildScrollView(
reverse: true,
child: Padding(
padding: EdgeInsets.only(bottom: bottom),
child: Container(...
Chris
  • 1,720
  • 16
  • 35
  • 1
    `padding: EdgeInsets.only(bottom: bottom)` throw an error: bottom must be a constant... how do you fix this? – Fabio Magarelli Jan 20 '20 at 18:40
  • 1
    Fabio you add`'final bottom = MediaQuery.of(context).viewInsets.bottom;` after `Widget _body(WriteReviewModel model) {` – Haris Feb 02 '20 at 02:27
  • This is the only thing that worked for me when composing a expanded multiline textfield in the bottom o a column, with ConstrainedBox and SingleChildScrollView. – jeanadam Feb 20 '20 at 02:38
  • 1
    On applying the above solution: The TextFormField which is already above the keyboard on gaining the focus it moves upwards and is not visible in the screen. Ideally it should stays there only only the below screen TextFormField should scroll up – Chinmay Mourya Jul 18 '22 at 11:47
20

You need to wrap everything in a SingleChildScrollView and set the reverse to true.

SingleChildScrollView(
   reverse: true,
   child: Container(),
);

Just that worked for me!

allentiology
  • 904
  • 8
  • 7
  • 7
    This is the simplest solution if your content does not scroll by default (without the keyboard showing up). Indeed if your content is larger than the screen height, it will always be scrolled to the bottom, even without keyboard. That may not be what you want. – Yann39 Jan 17 '21 at 11:24
12

I had a similar problem. I try all solution, but didn't work. Finally I removed

<item name="android:windowFullscreen">true</item>

from my styles.xml file in android folder, and fix the problem.

  • For me this is working in debug build, but in release build keyboard just coming up and hiding immediately, please confirm if this is the case for anyone? – Vamsi May 20 '20 at 08:22
  • 1
    No problem, it works fine both in debug and release. You must have another additional configuration that causes this. Try in clean project. – Guillermo De La Cruz May 20 '20 at 20:04
10

There are few methods for this (as of Dec 3rd 2018):

You can read this for a better solution: When i select a Textfield the keyboard moves over it.

Inside Scaffold() add: resizeToAvoidBottomPadding: false,.

You can also wrap your TextWidget with SingleChildScrollView(). This will allow you to scroll whenever the keyboard is shown.

Damiano Magrini
  • 460
  • 8
  • 17
Blasanka
  • 21,001
  • 12
  • 102
  • 104
4

Set resizeToAvoidBottomInset to false inside your Scaffold Widget.

Note that resizeToAvoidBottomPadding will be deprecated.

Scaffold( resizeToAvoidBottomInset: false, ...)
Jun
  • 160
  • 6
  • It took me way too long to learn about `resizeToAvoidBottomInset`. Every time I used a flex layout, my keyboards would break. It was awful. – Lewis Feb 11 '20 at 07:51
4

I use form elements in modal_bottom_sheet plugin. I solved it by just adding the following code to SingleChildScrollView.

padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom)
serkanayaz
  • 745
  • 6
  • 20
4

Too add to the commonly accepted answers here which is

body: SingleChildScrollView(
          reverse: true,
          child: Container(
              child: Padding(
            padding: EdgeInsets.only(bottom: bottom),
            child: Stack(
              fit: StackFit.loose,
              children: <Widget>[

I added a thing to the bottom inset to prevent it from going too high.

    var bottom = MediaQuery.of(context).viewInsets.bottom;
bottom = max(min(bottom, 80), 0);
David van Dugteren
  • 3,879
  • 9
  • 33
  • 48
2

What worked for me was combining the docs with tips over here. It uses, LayoutBuilder, SingleChildScrollView, Padding (with bottom hack) and finally, ConstrainedBox (to use Expanded). By combining these It works with Expanded widgets inside Columns.

The docs (from where LayoutBuilder comes): https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html

Structure

 return Scaffold(
      resizeToAvoidBottomInset: false,
      resizeToAvoidBottomPadding: false,`
body: SafeArea(
        child: Container(
          child: LayoutBuilder(builder:
              (BuildContext context, BoxConstraints viewportConstraints) {
            return SingleChildScrollView(
              reverse: true,
              child: Padding(
                padding: EdgeInsets.only(bottom: bottom),
                child: ConstrainedBox(
                  constraints: BoxConstraints(
                      minHeight: viewportConstraints.maxHeight,
                      maxHeight: viewportConstraints.maxHeight),
                  child: Column(
Boken
  • 4,825
  • 10
  • 32
  • 42
jeanadam
  • 419
  • 5
  • 5
1

SingleChildScrollView does solve the problem while the resizeToAvoidBottomInset is set to true, while setting it to false would be a not recommended solution. Let me explain why:

When user presses the TextField, usually a virtual keyboard will popup and takes up a large portion of the bottom space on the screen. In such case, problem would occur, if the TextField is near said bottom, it will be covered by the keyboard (resizeToAvoid... set to false), and user will be unable to see what they've typed in; if there are other widgets below the TextField (when resizeToAvoid is true, e.g. buttons in the same Column with TextField), there will be overflow because there is no space for them to show on the remaining viewport.

Speaking from a user's perspective, what we want is:

  1. TextField who gets focus is always visible.
  2. No bottom overflow and bugged graphics.

However, such description is not technical, it does not tell us how exactly do we implement it. What we actually want is, make the whole layout scrollable, and allow Scaffold to resize. When the viewport resizes, anything below the focused TextField scrolls away to the invisible bottom, and the TextField itself snaps to the keyboard.That's why SingleChildScrollView + resize = true is what we want.

linkfting
  • 164
  • 8
1

To have a centered content first on build method I added this:

final bottom = MediaQuery.of(context).viewInsets.bottom;

and return this:

return GestureDetector(
      onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
      child: Scaffold(
        resizeToAvoidBottomInset: false,
        body: Stack(
          fit: StackFit.expand,
          children: [
            ///Content
            Align(
              alignment: Alignment.center,
              child: SingleChildScrollView(
                reverse: true,
                child: Padding(
                  padding: EdgeInsets.only(bottom: bottom),
                  child: Column(
                    children: [
                      MyContent()
                    ],
                  ),
                ),
              ),
            ),
            ///Button
            Align(
              alignment: Alignment.bottomCenter,
              child: MyBottomButton()
            )
          ],
        ),
      ),
    );

And it works very well with keyboard flow

Álvaro Agüero
  • 4,494
  • 1
  • 42
  • 39
1

It's simple, forget about those complicated answers. You just need to use the scrollPadding method that's available in TextFormField:

TextFormField(
      scrollPadding: const EdgeInsets.only(bottom: 200),
),
Antomur
  • 41
  • 5
0

In my case, there was were important to use only small padding, otherwise when open the keyboard it makes a big mess.

Padding(padding: EdgeInsets.only(bottom: 20)

Check my solution:

child: Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,
    body: Container(
      color: Colors.black,
       child: SingleChildScrollView(
         reverse: true,
          child: Padding(
           padding: EdgeInsets.only(bottom: 20),
            child: Container(
              child: ReservationCard(
                ),
                  ),
                   ),
                    ),
                     )
Arvis Iljins
  • 335
  • 3
  • 10
-1

For Android, check for windowSoftInputMode. (AndroidManifest.xml)

android:windowSoftInputMode="adjustResize"

ScreenShoot AndroidManifest.xml

Lauro Oliveira
  • 2,362
  • 1
  • 18
  • 12