Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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


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.


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(
       -
       -
       -
        )
   )

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'),
        ),
      )
    );
  }

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(...)
      ),
    );
  }


Just as a small side note:

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

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

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)