3

I have the following code:

return Scaffold(
      appBar: AppBar(
        title: Text('Sample Code'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(20.0),
        children: <Widget>[
          TextField(
            decoration: InputDecoration(labelText: "Text"),
          ),
          TextField(
            decoration: InputDecoration(labelText: "Text"),
          ),
          TextField(
            decoration: InputDecoration(labelText: "Text"),
          ),
        ],
      ),
      bottomNavigationBar: BottomAppBar(
        child: Container(
          height: 50.0,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );

Whenever the keyboard shows up to enter text into a TextField the FloatingActionButton moves up to the top of the keyboard which will look like this:

FloatingActionButton

What I want is that the button stays in the bottom navigation bar and does not move when the keyboard shows up. I added resizeToAvoidBottomPadding: false, to the Scaffold, which prevents the button from moving but also stops my ListView from moving to stay visible when the keyboard shows up.

4 Answers 4

11

Wrapping the floating action button inside a positioned widget did not work for me. However, in combination to adding in your Scaffold the property

resizeToAvoidBottomPadding: false,

You can also use the SingleChildScrollView widget with padding using the MediaQuery.of method...

return Scaffold(
  resizeToAvoidBottomInset: false,
  backgroundColor: Colors.lightBlueAccent,
  floatingActionButton: FloatingActionButton(
    backgroundColor: Colors.lightBlueAccent,
    child: Icon(Icons.add),
    onPressed: () {
      showModalBottomSheet(
          context: context,
          isScrollControlled: true,
          builder: (context) => SingleChildScrollView(
              child: Container(
                  padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
                  child: AddTaskScreen())),
          backgroundColor: Colors.transparent);
    },
  ),
Sign up to request clarification or add additional context in comments.

Comments

3

Maybe there's a more elegant way of doing this? but this will solve your immediate problem.

There's a nice little plugin to detect the keyboard visibility here. All you need to do then is to listen to the keyboard visibility state and hide the FAB when the keyboard is visible.

Sample:

import 'package:flutter/material.dart';
import 'package:keyboard_visibility/keyboard_visibility.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SO Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool keyboardOpen = false;

  @override
  void initState() {
    super.initState();
    KeyboardVisibilityNotification().addNewListener(
      onChange: (bool visible) {
        setState(() => keyboardOpen = visible);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sample Code'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(20.0),
        children: <Widget>[
          TextField(decoration: InputDecoration(labelText: "Text")),
          TextField(decoration: InputDecoration(labelText: "Text")),
          TextField(decoration: InputDecoration(labelText: "Text")),
        ],
      ),
      bottomNavigationBar: BottomAppBar(
        child: Container(height: 50.0),
      ),
      floatingActionButton: keyboardOpen
          ? SizedBox()
          : FloatingActionButton(
              onPressed: () {},
              child: Icon(Icons.add),
            ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }
}

2 Comments

This solved my problem, thank you! But I'm still curious if there might be a more elegant way to handle this.
Yes, there is a more elegant way, which is using positioned widget. Have a look at here
1

Just use the property inside Scaffold resizeToAvoidBottomInset: false

It will solve the problem immediately..

Comments

0

inside Scaffold Use this property. resizeToAvoidBottomInset: false

Just Like :

return Scaffold(
resizeToAvoidBottomInset: false
      appBar: AppBar(
        title: Text('Sample Code'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(20.0),
        children: <Widget>[
          TextField(
            decoration: InputDecoration(labelText: "Text"),
          ),
          TextField(
            decoration: InputDecoration(labelText: "Text"),
          ),
          TextField(
            decoration: InputDecoration(labelText: "Text"),
          ),
        ],
      ),
      bottomNavigationBar: BottomAppBar(
        child: Container(
          height: 50.0,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.