Flutter: Detect keyboard open and close

DartFlutter

Dart Problem Overview


I have a BottomNavigationBar at the upper-most level of my application. I want to detect keyboard open and close basically anywhere in the app/subtree, so I can show and hide the BottomNavigationBar whenever the keyboard is visible.

This is a general issue and may not be directly related to the BottomNavigationBar. In other words, abstract from the BottomNavigationBar :-)

Dart Solutions


Solution 1 - Dart

To check for keyboard visibility, just check for the viewInsets property anywhere in the widget tree. The keyboard is hidden when viewInsets.bottom is equal to zero.

You can check for the viewInsets with MediaQuery like:

MediaQuery.of(context).viewInsets.bottom

Solution 2 - Dart

I just created a Flutter plugin to notify about keyboard open and close events. It works both on Android and iOS.

keyboard_visibility


import 'package:keyboard_visibility/keyboard_visibility.dart';

@override
void initState() {
  super.initState();

  KeyboardVisibilityNotification().addNewListener(
    onChange: (bool visible) {
      print(visible);
    },
  );
}

Solution 3 - Dart

You can use WidgetsBinding.instance.window.viewInsets.bottom. If its value is greater than 0.0 then the keyboard is visible.

    if(WidgetsBinding.instance.window.viewInsets.bottom > 0.0)
    {
       // Keyboard is visible.
    }
    else
    {
       // Keyboard is not visible.
    }

Solution 4 - Dart

You can use the keyboard_visibility package to do this effectively. I've used it, and it works like a charm.

To install

dependencies:
  keyboard_visibility: ^0.5.2

Usage

import 'package:keyboard_visibility/keyboard_visibility.dart';

@protected
void initState() {
  super.initState();

  KeyboardVisibilityNotification().addNewListener(
    onChange: (bool visible) {
      print(visible);
    },
  );
}

It also supports listeners like show/hide.

Here is the link.

Solution 5 - Dart

In your StatefullWidget, create a variable:

bool _keyboardVisible = false;

Then initialize that variable in the build widget;

@override
Widget build(BuildContext context) {
    _keyboardVisible = MediaQuery.of(context).viewInsets.bottom != 0;
    return child;
}

Solution 6 - Dart

You can use MediaQuery.of(context).viewInsets.bottom. Just look at the documentation below.

> > /// The parts of the display that are completely obscured by system UI, /// typically by the device's keyboard. /// /// When a > mobile device's keyboard is visible viewInsets.bottom /// > corresponds to the top of the keyboard. /// /// This value is > independent of the [padding]: both values are /// measured from the > edges of the [MediaQuery] widget's bounds. The /// bounds of the top > level MediaQuery created by [WidgetsApp] are the /// same as the > window (often the mobile device screen) that contains the app. ///
> /// See also: /// /// * [MediaQueryData], which provides some > additional detail about this /// property and how it differs from > [padding]. final EdgeInsets viewInsets;

Solution 7 - Dart

This is my solution, which uses WidgetsBindingObserver to observe window size changes, and determine whether the keyboard is hidden based on this.

/// My widget state,it can remove the focus to end editing when the keyboard is hidden.
class MyWidgetState extends State<MyWidget> with WidgetsBindingObserver {
  /// Determine whether the keyboard is hidden.
  Future<bool> get keyboardHidden async {
    // If the embedded value at the bottom of the window is not greater than 0, the keyboard is not displayed.
    final check = () => (WidgetsBinding.instance?.window.viewInsets.bottom ?? 0) <= 0;
    // If the keyboard is displayed, return the result directly.
    if (!check()) return false;
    // If the keyboard is hidden, in order to cope with the misjudgment caused by the keyboard display/hidden animation process, wait for 0.1 seconds and then check again and return the result.
    return await Future.delayed(Duration(milliseconds: 100), () => check());
  }

  @override
  void initState() {
    super.initState();
    // Used to obtain the change of the window size to determine whether the keyboard is hidden.
    WidgetsBinding.instance?.addObserver(this);
  }

  @override
  void dispose() {
    // stop Observing the window size changes.
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }
  
  @override
  void didChangeMetrics() {
    // When the window insets changes, the method will be called by the system, where we can judge whether the keyboard is hidden.
    // If the keyboard is hidden, unfocus to end editing.
    keyboardHidden.then((value) => value ? FocusManager.instance.primaryFocus?.unfocus() : null);
  }
}

Solution 8 - Dart

You can use Flutter keyboard visibility plugin

@override
Widget build(BuildContext context) {
  return KeyboardVisibilityBuilder(
    builder: (context, isKeyboardVisible) {
      return Text(
        'The keyboard is: ${isKeyboardVisible ? 'VISIBLE' : 'NOT VISIBLE'}',
      );
    }
  );

Solution 9 - Dart

With Flutter 2.0 and null safety, I use this package - it has no streams, pure Dart, gives additional information about keyboard height, etc.

flutter_keyboard_size 1.0.0+4

Enter image description here

Solution 10 - Dart

I used a workaround. I added a focusNode to the input and added a listener to that.

See the implementation here add focus listener to input.

Solution 11 - Dart

I found an easier solution here:

Put the DesiredBottomWidget in a Stack() with a Positioned(top: somevalue), and it will be hidden when the keyboard appears.

Example:

Stack(
    "Somewidget()",
    Positioned(
        top: "somevalue",
        child: "DesiredBottomWidget()"),
),

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJakob KristensenView Question on Stackoverflow
Solution 1 - DartHemanth RajView Answer on Stackoverflow
Solution 2 - Dartad eeView Answer on Stackoverflow
Solution 3 - Dartdeepak rajView Answer on Stackoverflow
Solution 4 - DartAbdulGafar Olamide AjaoView Answer on Stackoverflow
Solution 5 - DartAbdurahman PopalView Answer on Stackoverflow
Solution 6 - Dartkaushik samantaView Answer on Stackoverflow
Solution 7 - DartjqgsninimoView Answer on Stackoverflow
Solution 8 - DartM.AQIBView Answer on Stackoverflow
Solution 9 - DartawaikView Answer on Stackoverflow
Solution 10 - DartReuven KapiloffView Answer on Stackoverflow
Solution 11 - DartGustavo CartaxoView Answer on Stackoverflow