I am searching for a possibility to detect when the user taps the android back button on the bottom in order to close the keyboard in flutter. The problem is the following: If the user taps a text field, it gets the focus and the keyboard appears, everything is fine here. I put the text field inside a GestureDetector so if the user taps somewhere outside the text field, unfocus() is called. But on android there is another way to close the keyboard: Using the back button from the smartphone on the bottom. Is there any way to detect when the user taps it while the keyboard was open? As I understand, WillPopScope only works when the back button points to the left, but when the keyboard is opened, the back button points to the bottom and it has another purpose. The keyboard_visibility package did not work for me. When adding a listener to the KeyboardVisibilityNotification, the methods onHide and onChanged did not fire.

Solution 1: Rakesh R

Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(.....),
onWillPop: () async {
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
return false;
return true;

Use WillPopScope to close the keyboard on backpress event

Solution 2: Truls Matias Torgersen

Use the keyboard_visibility package: https://pub.dev/packages/keyboard_visibility.

The onHide callback does not fire for some reason, so you have to use onChange instead and check if the visibility is false.

Solution 3: Joel Hernández Fernández

Since the keyboard_visibility package is no longer updated, you can use this new one: Flutter Keyboard Visibility. It uses null safety and is getting updates.

Here is my approach, using the FocusManager instead of the FocusScope.

late final KeyboardVisibilityController _keyboardVisibilityController;
late StreamSubscription<bool> keyboardSubscription;

  void initState() {
    _keyboardVisibilityController = KeyboardVisibilityController();
    keyboardSubscription = _keyboardVisibilityController.onChange.listen((isVisible) {
      if (!isVisible) FocusManager.instance.primaryFocus?.unfocus();

  void dispose() {

See the package for alternative implementations.