15

Edit:

I got a report that this is a duplicate of When the keyboard appears, the Flutter widgets resize. How to prevent this?. While this is related, it is a different issue. I want the keyboard to overlap the UI until it reaches the TextField that has focus. This is default behavior on Android

Original:

I am an Android developer and just started with Flutter. I wanted to create a log in screen. I wanted an image above the TextField's. So I thought, I use a Stack to have the image on the background and some TextField's below.

The issue is that as soon as the keyboard appears, it pushes all content up. On Android, usually the keyboard only pushes up if necessary and only until it reaches the EditText.

I tried setting resizeToAvoidBottomPadding to false, but then nothing moves (of course) and the TextField's get covered by the keyboard.

I remember from playing around with iOS in the past, this is default behavior, maybe I should reconsider my layout?

At the moment, I wrap it in a ListView so that the user is able to scroll when the keyboard appears.

This is my layout (just for testing)

@override
Widget build(BuildContext context) {
  this.context = context;
  return new Scaffold(
      key: _scaffoldKey,
      body: new Stack(
          children: <Widget>[loginImage(), new Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[new TextField(), new TextField(),
        new TextField(), new TextField(),
        new TextField(), new TextField()],
      )])
  );
}

enter image description here: enter image description here

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Boy
  • 7,010
  • 4
  • 54
  • 68
  • this is a related stackoverflow question btw: https://stackoverflow.com/questions/46551268/when-the-keyboard-appears-the-flutter-widgets-resize-how-to-prevent-this/46551390 – Boy Apr 15 '18 at 12:22
  • Possible duplicate of [When the keyboard appears, the Flutter widgets resize. How to prevent this?](https://stackoverflow.com/questions/46551268/when-the-keyboard-appears-the-flutter-widgets-resize-how-to-prevent-this) – Jonah Williams Apr 15 '18 at 15:09
  • I mentioned the same in my comment, but the difference is that my question is on TextField focus – Boy Apr 15 '18 at 17:26
  • Do you have more than one Scaffold in your tree at the same time? – Günter Zöchbauer Apr 16 '18 at 07:22
  • nope, this is all there is – Boy Apr 16 '18 at 09:15

6 Answers6

45

I had this problem while setting autoFocus: true in a CupertinoTextField() and fixed it by setting resizeToAvoidBottomInset: false in Scaffold().

resizeToAvoidBottomPadding is deprecated now.

Use resizeToAvoidBottomInset.

Anirban Das
  • 1,035
  • 1
  • 18
  • 22
Hahnemann
  • 4,378
  • 6
  • 40
  • 64
  • 3
    Use `resizeToAvoidBottomInset : false`, `resizeToAvoidBottomPadding` is [deprecated](https://stackoverflow.com/a/56095293/5212904). – ArtiomLK May 12 '19 at 01:11
  • I tried `resizeToAvoidBottomInset: false` but now the `autoFocus: true` of the keyboard is not working – Ian Rajkumar Sep 27 '21 at 14:52
  • That causes the view I'm working with to go fullscreen and then go back to it's original size – lolelo Oct 01 '21 at 12:01
3

Also instead of Stack I suggest you use ListView. You could also on the other hand tryout SingleChildScrollView (but you might have to add extra codes for implementation).

Happy Coding...

The Billionaire Guy
  • 3,382
  • 28
  • 31
2

I think this does what you want. The biggest problem is that you chose to use a Stack. A stack is only used if you want to stack things on top of each other. In this case you don't want that. Placing it in a Column and filling the open space with an Expanded (This Widget expands to usable space and pushes everything down) is the way I do it. I don't say it's the best way (Only 2 weeks of flutter experience). But it's a way. I hope it helps!

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
        return new MaterialApp(
            title: 'Flutter Demo',
            theme: new ThemeData(
                primarySwatch: Colors.blue,
            ),
            home: new Scaffold(
                body: new Column(
                    children: <Widget>[
                        new Center(
                            child: new Container(
                                height: 150.0,
                                width: 75.0,
                                color: Colors.red,
                            ),
                        ),
                        new Expanded(
                            child: new Container(),
                        ),
                        new Column(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            mainAxisAlignment: MainAxisAlignment.end,
                            children: <Widget>[
                                new TextField(),
                                new TextField(),
                                new TextField(),
                                new TextField(),
                                new TextField(),
                                new TextField()
                            ],
                        ),
                    ],
                ),
            ),
        );
    }
}
Kevin Walter
  • 6,507
  • 8
  • 28
  • 32
  • 1
    This gives me the same issue. But I'm really glad you explained 'expanded' to me! I had issues of getting the column at the bottom. But the issue I actually was addressing, is that the keyboard pushes ALL the textfields up, while I expect the keyboard to overlap the textfields which are not focused – Boy Apr 15 '18 at 12:08
  • 1
    You only want the active (Focussed) textfield moving up with the keyboard? I have no idea on how to do that. Sorry. Still glad that I could help you with the Expanded class. – Kevin Walter Apr 15 '18 at 12:10
  • Seems to be a know issue: https://github.com/flutter/flutter/issues/13475 – Boy Apr 15 '18 at 12:20
2

Set this on scaffold:

  1. resizeToAvoidBottomInset: true

  2. Use stack to set your background.

    body: Stack(fit: StackFit.expand, children: <Widget>[
              Opacity(
                  opacity: 0.5,
                  child: Image.asset('lib/assets/images/background3.jpg',
                      fit: BoxFit.cover)),
              Padding(
                padding: EdgeInsets.all(20),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Header1(),
                    SizedBox(
                      height: 10,
                    ),
                    Tittle("Welcome to Bitetat's live repots"),
                    Expanded(
                      child: SingleChildScrollView(
                          physics: AlwaysScrollableScrollPhysics(),
                          child: Column(
                            mainAxisSize: MainAxisSize.min,
                            mainAxisAlignment: MainAxisAlignment.spaceAround,
                            children: <Widget>[
                              Container(

  1. There you can put your fields

Now you can enjoy nice background and your keyboard will not cover the fields and also scrollable.

Zach Jensz
  • 3,650
  • 5
  • 15
  • 30
1

It is default functionality of the Flutter. so, if you set resizeToAvoidBottomInset: false then you will lose the functionality of keeping your UI components above the keyboard. To have a background image in your application better way is to do it like this:

Container(
  decoration: BoxDecoration(
    color: primaryColor,
    image: DecorationImage(image: AssetImage(AppImages.appBg)),
  ),
  child: SafeArea(
    child: Scaffold(
      backgroundColor: Colors.transparent,
      body: //All Ui code here//
    ),
  ),
),

It is necessary to set Scaffold's backgroundColor: Colors.transparent otherwise, you won't be able to see your background image.

Shubham Sharma
  • 166
  • 1
  • 7
0

There also an alternate way instead of resizeToAvoidBottomInset

You can put the body of the Scaffold into SingleChildScrollView and apply physics to NeverScrollableScrollPhysics().

Scaffold(
        body: SingleChildScrollView(
          physics: NeverScrollableScrollPhysics(),
          child: Stack(
            children: [ ........