31

I am trying to create a simple To Do App in in flutter with a Floating Action Button in the bottom which when clicked show an Alert Dialog to add items to the list. Every time I click on the button, the Keyboard pushes the Action Button upward causing overflowing error. Is there any way to avoid pushing the action button upward when Keyboard is opened? Here is the snapshot I took: Snapshot Below the source code:

import 'package:flutter/material.dart';
import '../model/todo_item.dart';

class ToDoScreen extends StatefulWidget {
  @override
  _ToDoScreenState createState() => _ToDoScreenState();
}

class _ToDoScreenState extends State<ToDoScreen> {
  TextEditingController _textEditingController = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueAccent,
      body: Column(
        children: <Widget>[ToDoItem("Going for a Walk", "12 January, 2019")],
      ),
      floatingActionButton: FloatingActionButton(
        tooltip: 'Add Item',
        child: Icon(Icons.add),
        backgroundColor: Colors.red,
        onPressed: _showFormDialog,
      ),
    );
  }

  void _showFormDialog() {
    var alert = AlertDialog(
      content: Row(
        children: <Widget>[
          Expanded(
            child: TextField(
              controller: _textEditingController,
              autofocus: true,
              decoration: InputDecoration(
                  labelText: "Item",
                  hintText: "eg. Buy Vegetables",
                  icon: Icon(Icons.note_add)),
            ),
          )
        ],
      ),
      actions: <Widget>[
        FlatButton(
          onPressed: () {
            // _handleSubmit(_textEditingController.text);
            _textEditingController.clear();
          },
          child: Text("Save ToDo"),
        ),
        FlatButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text("Cancel"),
        )
      ],
    );
    showDialog(context: context, builder: (BuildContext context) => alert);
  }
}
Albert George
  • 321
  • 1
  • 3
  • 7
  • Use `ListView` instead of `Column` – EdHuamani Jan 09 '19 at 17:28
  • Thanks for the reply. Yes, I know I can use ListView instead of Column but my issue is how to stop floating button to get raised every time a keyboard is opened. Is there any work around to solve this problem? – Albert George Jan 12 '19 at 10:56

6 Answers6

69

I had the same issue, where my Floating Action Button would get pushed up.

I solved this using the property:

resizeToAvoidBottomPadding: false, // fluter 1.x
resizeToAvoidBottomInset: false // fluter 2.x

On the parent Scaffold.

I tested it with your code, it solves the issue as well.

MetaStack
  • 3,266
  • 4
  • 30
  • 67
  • This solves the problem. But what if I want the other widgets in my `Scafold` to resize, just not the Floating Action Button? – hoan May 16 '19 at 18:23
  • 9
    What if we need this property to be true, for example I have textfield which will be hidden by keyboard on opening. and I also have floating action button. Any idea? – Developine Dec 23 '19 at 08:39
  • In Flutter 2.0, the property has been changed to `resizeToAvoidBottomInset` – Muhammad Faizan Apr 25 '21 at 07:16
23

You can check if the keyboard is show up or not, and based on that create the floating button or not.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: keyboardIsOpened ? 
          null ://or an empty container
          FloatingActionButton(
          tooltip: 'Add Item',
          child: Icon(Icons.add),
          backgroundColor: Colors.red,
          onPressed: _showFormDialog,
      ),
    );
  }

Inside the build method you can know if the keyboard show up by using MediaQuery.of(context).viewInsets.bottom and save its value on a bool variable keyboardIsOpened like the following code.

@override
Widget build(BuildContext context) {
  bool keyboardIsOpened = MediaQuery.of(context).viewInsets.bottom != 0.0;
apxcode
  • 7,696
  • 7
  • 30
  • 41
Abdelazeem Kuratem
  • 1,324
  • 13
  • 20
  • 1
    I used this method. It's a simple solution that gets right to the problem. Additionally you can wrap the floating action button in a Visibility() widget. then just setup the visibility parameter based on the keyboardIsOpened variable. ~~~ floatingActionButton: Visibility( visibility: keyboardIsOpened ? false : true, child: FloatingActionButton(), ); ~~~ That way you won't have the annoying animation of the floating action button shrinking when the keyboard is opened. – David Hegner Jun 08 '20 at 23:50
  • I used this solution for the first time but I faced a problem with the floating button because it is still there on the screen but it is just invisible so if you touch the screen above the keyboard by mistake, you may press it. so I prefer to remove it until I finish using the keyboard. – Abdelazeem Kuratem Jul 02 '20 at 19:08
  • This answer is dangerous. `viewInsets` is not just for the keyboard. – apxcode May 06 '21 at 22:21
  • @apxcode what do you suggest other than using this and `resizeToAvoidBottomInset: false`?? – Ahmad Khan Nov 30 '21 at 10:40
  • There is a library for detecting keyboard called keyboard visibility @Ahmad Khan – Anan Saadi Dec 01 '21 at 05:01
16

To prevent the keyboard from pushing the FloatingActionButton (FAB) upwards in your Flutter app, you can use the MediaQuery and Visibility widgets.

The MediaQuery widget provides access to information about the current device screen. By checking the value of viewInsets.bottom, we can determine whether the keyboard is open or closed. If viewInsets.bottom is zero, it indicates that the keyboard is closed.

To implement this solution, wrap your FAB widget with the Visibility widget and set the visible property to the condition MediaQuery.of(context).viewInsets.bottom == 0.0. This ensures that the FAB remains visible when the keyboard is closed and hidden when the keyboard is open.

use Visibility with the FAB:

Visibility(
  visible: MediaQuery.of(context).viewInsets.bottom == 0.0,
  child: FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.chat),
  ),
),

With this implementation, the FAB will be visible when the keyboard is closed, and it will disappear when the keyboard is open, providing a consistent user interface.

BIS Tech
  • 17,000
  • 12
  • 99
  • 148
1

Wrap your complete code in this

 new Container(
child: Column(
children: <Widget>[
        Expanded(
          child: SingleChildScrollView(
            child: Stack(
              children: <Widget>[
              // Your body code
              ] // Widget
             ), // Stack
            ), // SingleChildScrollView
           ), // Expanded
        Container(
        alignment: Alignment.bottomCenter,
        padding: EdgeInsets.all(10.0),
        child : 
        // button code here 
        // to make button full width use minWidth: double.infinity,
         ,
        ), //Container
        ], // Widget
        ), // Column
        ), // Container
Harsh Kashyap
  • 256
  • 2
  • 5
0

Wrapping the Floating Action Button inside a column together with my bottom navigation, then passing this as the child to my bottom navigation bar solved most of the stated concerns: Also ensure you add mainAxisSize: MainAxisSize.min,to your column.

Dharman
  • 30,962
  • 25
  • 85
  • 135
0

i try this so good

Visibility(
      visible: MediaQuery.of(context).viewInsets.bottom == 0.0,
      child: FloatingActionButton(
        onPressed: () {},
        child: Icon(Icons.chat),
      ),
    ),
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 13 '22 at 17:27