Flutter move screen up on the keyboard

eye-catchDart and Flutter

Scaffold widget has persistentFooterButton property. When we assign widgets there they are hidden under the keyboard. resizeToAvoidBottomInset = true doesn’t work for the property. How can we show the footer on the keyboard? Let’s learn how to solve it in this article.

Sponsored links

Confirm the problem with actual code

Firstly, let’s check if the persistent footer button is really hidden. The following view has multiple TextField and two buttons defined on the persistent footer.

class ScaffoldFooterView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: PageView(
        children: [
          _createFloating(),
          _createPersistentFooter(),
          _createPersistentFooter2(),
        ],
      ),
    );
  }
  Widget _createPersistentFooter() {
    return Scaffold(
      appBar: AppBar(
        title: Text("Persistent Footer Button"),
      ),
      body: ListView(
        children: [
          TextField(),
          TextField(),
          TextField(),
          TextField(),
          TextField(),
        ],
      ),
      persistentFooterButtons: [
        Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            ElevatedButton(onPressed: () {}, child: Text("Cancel")),
            ElevatedButton(onPressed: () {}, child: Text("OK")),
          ],
        ),
      ],
    );
  }
}

The buttons are shown on the bottom but they are under the keyboard when trying to input text.

floatingActionButton is always on keyboard

Let’s try to define floatingActionButton instead. The code is following.

Widget _createFloating() {
  return Scaffold(
    appBar: AppBar(
      title: Text("Floating Button"),
    ),
    body: ListView(
      children: [
        TextField(),
        TextField(),
        TextField(),
        TextField(),
        TextField(),
        TextField(),
      ],
    ),
    floatingActionButton: Row(
      mainAxisSize: MainAxisSize.max,
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        ElevatedButton(onPressed: () {}, child: Text("Cancel")),
        ElevatedButton(onPressed: () {}, child: Text("OK")),
      ],
    ),
  );
}

As you can see the following video, it works as expected although we need to adjust the layout of the buttons. The cancel button is not shown properly when specifying MainAxisAlignment.spaceBetween. In addition to that, it is shown on the body widget. It’s not good.

We may be able to fill out the color on the widget but body contents are still under the floating action button. It means that the last item can be invisible.

Define persistentFooterButtons in child Scaffold

body of Scaffold is always displayed. If we define all necessary contents on body property it is definitely shown, right? Let’s move the Scaffold widget into the child widget.

Widget _createPersistentFooter2() {
  return Scaffold(
    // appear on the keyboard
    appBar: AppBar(
      title: Text("Scaffold in Scaffold"),
    ),
    body: _createPersistentFooter(),
  );
}

All necessary contents are defined on body property now. Since persistentFooterButtons is also on body property, it should be shown as we expect.

We don’t have to do additional adjustments to the layout.

End

If you want to try it yourself you can clone my repository.

GitHub - yuto-yuto/flutter_samples
Contribute to yuto-yuto/flutter_samples development by creating an account on GitHub.

Comments

Copied title and URL