How to monitor the closing of keyboard pop-up in flutter

Time:2021-4-25

preface

Recently, when I was working on the company’s flutter project, I received a demand that the essence of it is to realize the function of losing the focus of textfield component when I put away the keyboard.

At first glance, this demand is easy to solve, I thought, that’s it! That’s it! That’s it! so easy!

But! But! But! I never thought it would make my thin hair worse when I realized it. The reason is that the third-party input method of Android mobile phone has a very painful place, that is, it will have a button to put away the keyboard, as shown in the figure below:
How to monitor the closing of keyboard pop-up in flutter
That’s the problem! One! Press! Button! It does not belong to the native keyboard button, unable to detect keyboard events! And can’t shield! It’s really going to collapse. Now let’s talk about my final solution to the problem for brother Meng. I hope it can help!

Thinking of solving problems

As mentioned above, keyboard events cannot be monitored, so I can only find another way. Can the monitor keyboard be turned off? Through a search, the answer is yes, so let’s do it!

keyboard_visibility

Address:https://pub.dev/packages/keyb…

This library can be used to monitor the pop-up and collapse of the keyboard

import 'package:keyboard_visibility/keyboard_visibility.dart';

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

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

Generally speaking, this can completely solve our needs, but! It’s not that simple! After upgrading the version of flutter, we found that APK couldn’t be packaged, and the final prompt was “keyboard”_ Visibility no! Also! Rong! Check the information found that this library should be the author stopped more, did not do with the times, this how the whole!

How to monitor the closing of keyboard pop-up in flutter

Due to the lack of relevant information on the Internet, the scientific Internet can not solve my problem immediately. I have no choice but to change my mind. Can I monitor the height change of the interface? After searching for information, the conclusion is that this can be done.

WidgetsBindingObserver & didChangeMetrics

This component can monitor some life cycles of the page, and there is a callback didchangemetrics to monitor changes in the height of the interface. Among them, the pop-up and put away of the keyboard are actually height changes, which can be monitored naturally.

Nice! See here, then we have a solution, that is to set a flag to distinguish when the keyboard pops up and when the keyboard is folded up.

class _InputState extends State<Input> with WidgetsBindingObserver {
  //Focus instance of input box
  FocusNode _focusNode;
  //Is the current keyboard active
  bool isKeyboardActived = false;

  @override
  void initState() {
    super.initState();
    _focusNode = FocusNode();
   //Monitor input box focus change
    _focusNode.addListener(_onFocus);
    //Create an observer of interface changes
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeMetrics() {
    super.didChangeMetrics();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      //It's currently Android and in focus
      if (Platform.isAndroid && _focusNode.hasFocus) {
        if (isKeyboardActived) {
          isKeyboardActived = false;
          //Causes the input box to lose focus
          _focusNode.unfocus();
          return;
        }
        isKeyboardActived = true;
      }
    });
  }

  //Since there is monitoring, of course, there must be unloading to prevent memory leakage
  @override
  void dispose() {
    super.dispose();
    _focusNode.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }

  //Function triggered when focus changes
  _onFocus() {
    if (_focusNode.hasFocus) {
      //Operation during focusing
      return;
    }
    
    //Operation when losing focus
    isKeyboardActived = false;
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      focusNode: _focusNode,
      textInputAction: TextInputAction.done,
    );
  }
}

This is a great success. After the test, there is no big problem, so it is easy to use.

Reference article

Widgetsbindingobserver monitors page lifecycle

Life cycle of flutter (interaction)

epilogue

This is probably the end of sharing. It took me a long time to solve this problem. It’s really hard for me. Of course, it may be because of my 10% discount on water bottle. If you need to share this time, you can also make a reference. If there is any better solution, big guy will teach me, refill refill.

To make complaints about the development of flutter, there are still many pits. Chatting with colleagues is more than once. The surrounding ecology of Tucao flutter is really fragile. It is hard to compare RN next door. And through this thing, I realized that if the cross platform thing is easy to solve with native components, try not to use related libraries. Otherwise, the whole compatibility problem will not be solved into a brine egg one day.