How to hide soft input keyboard on flutter after clicking outside TextField/anywhere on screen?

FlutterDartKeyboardHide

Flutter Problem Overview


Currently, I know the method of hiding the soft keyboard using this code, by onTap methods of any widget.

FocusScope.of(context).requestFocus(new FocusNode());

But I want to hide the soft keyboard by clicking outside of TextField or anywhere on the screen. Is there any method in flutter to do this?

Flutter Solutions


Solution 1 - Flutter

You are doing it in the wrong way, just try this simple method to hide the soft keyboard. you just need to wrap your whole screen in the GestureDetector method and onTap method write this code.

        FocusScope.of(context).requestFocus(new FocusNode());

Here is the complete example:

new Scaffold(

body: new GestureDetector(
  onTap: () {
   
    FocusScope.of(context).requestFocus(new FocusNode());
  },
child: new Container(
   //rest of your code write here
    )
 )

Updated (May 2021)

return GestureDetector(
      onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
      child: Scaffold(
        appBar: AppBar(
          title: Text('Login'),
        ),
        body: Body(),
      ),
    );

This will work even when you touch the AppBar, new is optional in Dart 2. FocusManager.instance.primaryFocus will return the node that currently has the primary focus in the widget tree.

Conditional access in Dart with null-safety

Solution 2 - Flutter

Updated

Starting May 2019, FocusNode now has unfocus method: > Cancels any outstanding requests for focus. > > This method is safe to call regardless of whether this node has ever requested focus.

Use unfocus if you have declared a FocusNode for your text fields:

final focusNode = FocusNode();

// ...

focusNode.unfocus();

My original answer suggested detach method - use it only if you need to get rid of your FocusNode completely. If you plan to keep it around - use unfocus instead.

If you have not declared a FocusNode specifically - use unfocus for the FocusScope of your current context:

FocusScope.of(context).unfocus();

See revision history for the original answer.

Solution 3 - Flutter

Wrap whole screen in GestureDetector as

new Scaffold(
  
  body: new GestureDetector(
      onTap: () {
        // call this method here to hide soft keyboard
        FocusScope.of(context).requestFocus(new FocusNode());
      },
    child: new Container(
       -
       -
       -
        )
   )

Solution 4 - Flutter

I've added this line

behavior: HitTestBehavior.opaque,

to the GestureDetector and it seems to be working now as expected.

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context).calculatorAdvancedStageTitle),
      ),
      body: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () {
          FocusScope.of(context).requestFocus(new FocusNode());
        },
        child: Padding(
          padding: const EdgeInsets.only(
            left: 14,
            top: 8,
            right: 14,
            bottom: 8,
          ),
          child: Text('Work'),
        ),
      )
    );
  }

Solution 5 - Flutter

Just as a small side note:

If you use ListView its keyboardDismissBehavior property could be of interest:

ListView(
  keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
  children: [],
)

Solution 6 - Flutter

As of Flutters latest version v1.7.8+hotfix.2, you can hide keyboard using unfocus() instead of requestfocus()

FocusScope.of(context).unfocus()

so whenever you tap in the body part keyboard gets hidden

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text("Login"),
      ),
      body: GestureDetector(
        onTap: () {
          FocusScope.of(context).unfocus();
        },
        child: Container(...)
      ),
    );
  }

Solution 7 - Flutter

If you want the behavior to be accessible on any screen in your app, wrap MaterialApp with GestureDetector:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        FocusScopeNode currentFocus = FocusScope.of(context);

        if (!currentFocus.hasPrimaryFocus) {
          currentFocus.unfocus();
        }
      },
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
      ),
    );
  }
}

Checking hasPrimaryFocus is necessary to prevent Flutter from throwing an exception when trying to unfocus the node at the top of the tree.

(Originally given by James Dixon of the Flutter Igniter blog)

Solution 8 - Flutter

GestureDetector(
  onTap: () {
        FocusScope.of(context).requestFocus(FocusNode());
  },
  behavior: HitTestBehavior.translucent,
  child: rootWidget
)

Solution 9 - Flutter

onPressed: () {
    FocusScope.of(context).unfocus();
},

This works for me.

Solution 10 - Flutter

This will work in the latest flutter version.

GestureDetector(
  onTap: () {
    FocusScopeNode currentFocus = FocusScope.of(context);

    if (!currentFocus.hasPrimaryFocus &&
        currentFocus.focusedChild != null) {
      FocusManager.instance.primaryFocus.unfocus();
    }
  },
  child: MaterialApp(
    theme: ThemeData.dark().copyWith(
      primaryColor: Color(0xFF0A0E21),
      scaffoldBackgroundColor: Color(0xFF0A0E21),
    ),
    home: LoginUI(),
  ),
);

Solution 11 - Flutter

If the focus is inside a webview, keyboard open from another screen or any other then use the below way to hide the keyboard

import 'package:flutter/services.dart';

SystemChannels.textInput.invokeMethod('TextInput.hide');

This worked better than the solution to add FocusScope.of(context).unfocus() as that solution put me into a loop of the keyboard being shown and hidden

Solution 12 - Flutter

I just developed a small package to give any widget the kind of behavior you are looking for: keyboard_dismisser on pub.dev. You can wrap the whole page with it, so that the keyboard will get dismissed when tapping on any inactive widget.

Solution 13 - Flutter

If you want to do this "the right way", use Listener instead of GestureDetector.

GestureDetector will only work for "single taps", which isn't representative of all possible gestures that can be executed.

Listener(
  onPointerDown: (_) {
    FocusScopeNode currentFocus = FocusScope.of(context);
    if (!currentFocus.hasPrimaryFocus) {
      currentFocus.focusedChild.unfocus();
    }
  },
  child: MaterialApp(...),
);

Solution 14 - Flutter

Best for me.

I wrap since Material App because global outside touch

FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
  FocusManager.instance.primaryFocus.unfocus();
}

Resolve below,

I check Platform iOS only because Android can dismiss the keyboard the back button.

Listener(
  onPointerUp: (_) {
    if (Platform.isIOS) {
      FocusScopeNode currentFocus = FocusScope.of(context);
      if (!currentFocus.hasPrimaryFocus &&
          currentFocus.focusedChild != null) {
        FocusManager.instance.primaryFocus.unfocus();
      }
    }
  },
  child: MaterialApp(
    debugShowCheckedModeBanner: true,
    home: MyHomePage(),
    ...
  ),
),

So happy your coding.

Flutter version

enter image description here

Solution 15 - Flutter

so easy solution for beginner here is the smoothest solution for you while you need to hide-keyboard when user tap on any area of screen. hope its help you a lot.

Step - 1 : you need to create this method in Global class,

this method wrap you main widget into GestureDetector so when user tap outside the textfield it will hide keyboard automatically

Widget hideKeyboardWhileTapOnScreen(BuildContext context, {MaterialApp child}){

  return GestureDetector(
    onTap: () {
      if (Platform.isIOS) { //For iOS platform specific condition you can use as per requirement
        SystemChannels.textInput.invokeMethod('TextInput.hide');
        print("Keyboard Hide");
      }      
    },
    child: child,
  );
}

this method wrap you main widget into Listener so when user touch and scroll up it will hide keyboard automatically

Widget hideKeyboardWhileTapOnScreen(BuildContext context, {MaterialApp child}){
  return Listener(
    onPointerUp: (_) {
      if (Platform.isIOS) {
        FocusScopeNode currentFocus = FocusScope.of(context);
        if (!currentFocus.hasPrimaryFocus &&
            currentFocus.focusedChild != null) {
          FocusManager.instance.primaryFocus.unfocus();
          print("Call keyboard listner  call");
        }
      }
    },
    child: child,
  );
}

Step - 2 : here is how to use Global method

@override
Widget build(BuildContext context) {
 
  return hideKeyboardWhileTapOnScreen(context,
    child: MaterialApp(
        debugShowCheckedModeBanner: false, home: Scaffold(body: setAppbar())),
  );
}

Widget setAppbar2() {
  return MaterialApp(
    debugShowCheckedModeBanner: false,
    theme: ThemeData(primarySwatch: Colors.orange),
    home: Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: AppBar(),
    ),
  );
}

Solution 16 - Flutter

FocusScopeNode currentFocus = FocusScope.of(context);

    if (!currentFocus.hasPrimaryFocus) {
      currentFocus.unfocus();
    }

You should check here https://flutterigniter.com/dismiss-keyboard-form-lose-focus/

Solution 17 - Flutter

try this if you are on a stack

body: GestureDetector(
              onTap: () {
                FocusScope.of(context).requestFocus(new FocusNode());
              },
              child: Container(
                height: double.infinity,
                width: double.infinity,
                color: Colors.transparent,
                child: Stack(children: [
                  _CustomBody(_),
                  Positioned(
                      bottom: 15, right: 20, left: 20, child: _BotonNewList()),
                ]),
              ),
            ),

Solution 18 - Flutter

This will work

 Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return GestureDetector(
  onTap: () {
    FocusScopeNode focus = FocusScope.of(context);
    if (!focus.hasPrimaryFocus && focus.focusedChild != null) {
      focus.focusedChild.unfocus();
    }
  },
  child: MaterialApp(
    title: 'Flutter Demo',

Solution 19 - Flutter

It is true what maheshmnj said that from version v1.7.8+hotfix.2, you can hide keyboard using unfocus() instead of requestfocus().

FocusScope.of(context).unfocus()

But in my case I was still presented with a lot of layout errors, as the screen I navigated to was not capable of handling the layout.

════════ Exception Caught By rendering library ═════════════════════════════════
The following JsonUnsupportedObjectError was thrown during paint():
Converting object to an encodable object failed: Infinity
When the exception was thrown, this was the stack
#0      _JsonStringifier.writeObject  (dart:convert/json.dart:647:7)
#1      _JsonStringifier.writeMap  (dart:convert/json.dart:728:7)
#2      _JsonStringifier.writeJsonValue  (dart:convert/json.dart:683:21)
#3      _JsonStringifier.writeObject  (dart:convert/json.dart:638:9)
#4      _JsonStringifier.writeList  (dart:convert/json.dart:698:9)

This was handled by inserting "resizeToAvoidBottomInset: false" in the receiving screens Scaffold()

@override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,   // HERE
      appBar: AppBar(
        centerTitle: true,
        title: Text("Receiving Screen "),
      ),
      body: Container(...)
      ),
    );
  }

Solution 20 - Flutter

This is best

Scaffold(
body: GestureDetector(
  onTap: () {
   if (messageFocusNode.hasFocus) {
 	 messageFocusNode.unfocus();
 }
},
child: new Container(
   //rest of your code write here
    )
 )

Solution 21 - Flutter

With Flutter 2.5 GestureDetector.OnTap hasn't worked for me.

Only this worked:

return GestureDetector(
      //keyboard pop-down
      onTapDown: (_) => FocusManager.instance.primaryFocus?.unfocus(),
      behavior: HitTestBehavior.translucent,
      child: Scaffold(

Solution 22 - Flutter

UPDATE NOVEMBER 2021

According to the new flutter webview documentation: Putting this piece of code inside the given full example will solve the keyboard dismiss the issue.

@override
   void initState() {
     super.initState();
         // Enable hybrid composition.
         if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
   }

Full example code:

 import 'dart:io';
 import 'package:webview_flutter/webview_flutter.dart';

 class WebViewExample extends StatefulWidget {
   @override
   WebViewExampleState createState() => WebViewExampleState();
 }

 class WebViewExampleState extends State<WebViewExample> {
   @override
   void initState() {
     super.initState();
         // Enable hybrid composition.
 if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
   }

   @override
   Widget build(BuildContext context) {
     return WebView(
       initialUrl: 'https://flutter.dev',
     );
   }
 }

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
QuestionAmmy KangView Question on Stackoverflow
Solution 1 - FlutterDaizy AroraView Answer on Stackoverflow
Solution 2 - FlutterGeorgeView Answer on Stackoverflow
Solution 3 - Flutteruser10147701View Answer on Stackoverflow
Solution 4 - FlutteratereshkovView Answer on Stackoverflow
Solution 5 - FlutteromnesiaView Answer on Stackoverflow
Solution 6 - FlutterMahesh JamdadeView Answer on Stackoverflow
Solution 7 - FlutterCharden DaxicenView Answer on Stackoverflow
Solution 8 - FlutterVyacheslavView Answer on Stackoverflow
Solution 9 - FlutterNixon KosgeiView Answer on Stackoverflow
Solution 10 - FluttershubhamView Answer on Stackoverflow
Solution 11 - FlutterParesh MangukiyaView Answer on Stackoverflow
Solution 12 - FlutterdrogelView Answer on Stackoverflow
Solution 13 - FlutterRudresh NarwalView Answer on Stackoverflow
Solution 14 - FlutterbamosszaView Answer on Stackoverflow
Solution 15 - FlutterHarikant AmiparaView Answer on Stackoverflow
Solution 16 - FlutterBurak Can KurtarırView Answer on Stackoverflow
Solution 17 - FlutterVictor Nieve MaquiView Answer on Stackoverflow
Solution 18 - FlutterRamshankar TVView Answer on Stackoverflow
Solution 19 - FlutterBo KristensenView Answer on Stackoverflow
Solution 20 - FlutterPinkesh DarjiView Answer on Stackoverflow
Solution 21 - FlutterItsastickupView Answer on Stackoverflow
Solution 22 - FluttercodeloneView Answer on Stackoverflow