Hide FAB when onscreen keyboard appear
Asked Answered
F

6

31

In Flutter, how to make FAB button hide when onscreen keyboard appear?

FAB button cover up other element when on screenkeyboard show up.

enter image description here

Flatboat answered 19/1, 2018 at 9:2 Comment(0)
M
36

Wrap your FloatingActionButton with a Visibility widget and control the visibility with a bool value.

Snippet:
Widget build(context) {
  bool keyboardIsOpen = MediaQuery.of(context).viewInsets.bottom != 0;
  return Scaffold(
    body: // ...
    floatingActionButton: Visibility(
      visible: !keyboardIsOpen,
      child: // your FloatingActionButton
    ),
  );
}

This solution also gets rid of the animation when the button disappears and appears.

Be sure that the class extends StatefulWidget and you have created a state for it

Magavern answered 18/9, 2020 at 1:2 Comment(3)
I would prefer this solution over the answered oneNard
great solution, but no need for variable or StatefulWidget, simplify as... visible:MediaQuery.of(context).viewInsets.bottom == 0Gorse
I implemented this in my project. Working only in two of the screens and the rest is not changing.Obel
H
54

You can achieve it by checking for keyboard visibility using viewInsets and hide fab based on it.

Example:

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    title: "Example",
    home: new FabHideOnKeyboard(),
  ));
}

class FabHideOnKeyboard extends StatefulWidget {
  @override
  _FabHideOnKeyboardState createState() => new _FabHideOnKeyboardState();
}

class _FabHideOnKeyboardState extends State<FabHideOnKeyboard> {
  @override
  Widget build(BuildContext context) {
    final bool showFab = MediaQuery.of(context).viewInsets.bottom==0.0;
    return Scaffold(
      resizeToAvoidBottomPadding: true,
      body:Container(
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("TextField:"),
            TextField()
          ],
        ),
      ),
      floatingActionButton: showFab?Icon(Icons.add):null,
    );
  }
}
Hesiod answered 22/1, 2018 at 13:23 Comment(3)
Isn't MediaQuery.of(context) will trigger the rebuild everytime when that value change and then it will trigger rebuild again... which end up in a loop ?Luis
this causes the widget to rebuild.Gaze
@CharlesC, it will rebuild, and this is ok, even though if you don't use MediaQuery.of(context). Because when you trigger a focus, screen should rebuild.Disorganization
M
36

Wrap your FloatingActionButton with a Visibility widget and control the visibility with a bool value.

Snippet:
Widget build(context) {
  bool keyboardIsOpen = MediaQuery.of(context).viewInsets.bottom != 0;
  return Scaffold(
    body: // ...
    floatingActionButton: Visibility(
      visible: !keyboardIsOpen,
      child: // your FloatingActionButton
    ),
  );
}

This solution also gets rid of the animation when the button disappears and appears.

Be sure that the class extends StatefulWidget and you have created a state for it

Magavern answered 18/9, 2020 at 1:2 Comment(3)
I would prefer this solution over the answered oneNard
great solution, but no need for variable or StatefulWidget, simplify as... visible:MediaQuery.of(context).viewInsets.bottom == 0Gorse
I implemented this in my project. Working only in two of the screens and the rest is not changing.Obel
O
11

I hope this is what you are looking for

Scaffold(resizeToAvoidBottomInset: false)
Ocd answered 11/2, 2022 at 20:11 Comment(2)
Perfect for my use case.Dinka
a simple one linerLust
L
2

For future reference, this is an implementation following the basic idea from https://github.com/flutter/flutter/issues/26100 but using already existing mixins to reduce quirks and code:

class FixedCenterDockedFabLocation extends StandardFabLocation
    with FabCenterOffsetX, FabDockedOffsetY {
  const FixedCenterDockedFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.fixedCenterDocked';

  @override
  double getOffsetY(
      ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    final double contentBottom = scaffoldGeometry.contentBottom;
    final double bottomMinInset = scaffoldGeometry.minInsets.bottom;
    if (bottomMinInset > 0) {
      // Hide if there's a keyboard
      return contentBottom;
    }
    return super.getOffsetY(scaffoldGeometry, adjustment);
  }
}

You can then use it as simple as floatingActionButtonLocation: const FixedCenterDockedFabLocation(), (don't forget the const ;)).

Feel free to use this code without limitations or attribution.

Lection answered 29/7, 2021 at 8:11 Comment(0)
L
2
Widget build(context) {
  return Scaffold(
    resizeToAvoidBottomInset: false,
    appBar: // ...
    body: // ...
    floatingActionButton: Visibility(
      child: // your FloatingActionButton
    ),
  );
}
Leavings answered 28/2, 2022 at 12:28 Comment(3)
Your answer could be improved by adding more information on what the code does and how it helps the OP.Wadmal
i just added resizeToAvoidBottomInset: false, in scaffold widget. It works for me to hide floating action button.Leavings
Please read "How to Answer". It helps more if you supply an explanation why this is the preferred solution and explain how it works. We want to educate, not just provide code.Selfexecuting
V
1
Widget build(context) {


 bool iskeyboardOpen = MediaQuery.of(context).viewInsets.bottom != 0;
  return Scaffold(
    body: Container()// ...
    floatingActionButton: Visibility(
      visible: !iskeyboardOpen,
      child: DashboardActionButton(
            onTap: () {
              Navigator.push(context, MaterialPageRoute(builder: (c) {
                return const YourPage();
              })).then((_) {
                AsyncOrderActions(store).fetchData();
              });
            },
            svgIcon: 'send-white',
          ), // your FloatingActionButton
    ),
  );
}
Venereal answered 4/5, 2023 at 9:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.