This article shows you a simple way to dismiss the soft keyboard when the user taps somewhere outside a text field in your Flutter app.
What is the point?
A realistic scenario
If you use a TextField (or TextFormField) with a regular keyboard, there will be a “Done” button and when this button is pressed, the virtual keyboard will automatically disappear. However, with the numeric keypad on iOS, there is no “Done” button. So we have to help the user hide that keyboard somehow.
This is just one of many situations we might encounter when developing apps.
The Strategy
To make the keyboard go away itself, we need to remove “focus” from all of our text fields (if your app has more than one text field) by calling the unfocus() method:
FocusManager.instance.primaryFocus?.unfocus();
For more clarity, see the example below.
A complete example
Preview
Here’s how our sample app works on iOS and Android:
The Code
Here are the 2 main steps to produce the demo app you’ve seen in the preceding section:
1. Create a new widget called DismissKeyboard (this is a reusable widget that can be used in any Flutter application without having to edit the code):
// The DismissKeybaord widget (it's reusable)
class DismissKeyboard extends StatelessWidget {
final Widget child;
const DismissKeyboard({Key? key, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus &&
currentFocus.focusedChild != null) {
FocusManager.instance.primaryFocus?.unfocus();
}
},
child: child,
);
}
}
2. Wrap your entire app with the DismissKeyboard widget we’ve made before, like this:
// Wrap MaterialApp with our DismissKeyboard widget
DismissKeyboard(
child: MaterialApp(
/* Other code */
),
);
This ensures that if your app has multiple screens it will work everywhere without having to add the DismissKeyboard widget in multiple places.
The complete code:
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// Wrap MaterialApp with our DismissKeyboard widget
return DismissKeyboard(
child: MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Kindacode.com',
theme: ThemeData(primarySwatch: Colors.green),
home: const HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Kindacode.com'),
),
body: const Padding(
padding: EdgeInsets.all(30),
child: Center(
child: TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: 'A Text Field',
border: OutlineInputBorder(),
),
),
),
),
);
}
}
// The DismissKeybaord widget (it's reusable)
class DismissKeyboard extends StatelessWidget {
final Widget child;
const DismissKeyboard({Key? key, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus &&
currentFocus.focusedChild != null) {
FocusManager.instance.primaryFocus?.unfocus();
}
},
child: child,
);
}
}
Note that you can separate the DismissKeyboard class into a separate file so that your project will be easier to maintain.
Conclusion
You’ve learned a technique to hide the soft keyboard when the user touches somewhere outside the text field of your app. If you’d like to explore more new and interesting stuff about Flutter and mobile development, take a look at the following articles:
- Using GetX (Get) for Navigation and Routing in Flutter
- Using GetX (Get) for State Management in Flutter
- Flutter and Firestore Database: CRUD example
- Flutter: Customizing the TextField’s Underline
- Flutter form validation example
- /Flutter: Making Beautiful Chat Bubbles (2 Approaches)
You can also check out our Flutter category page, or Dart category page for the latest tutorials and examples.
Took 2 seconds (Exaggerated, but you get the point) to implement! Thanks.
awsome
Thank you!!!!!
Thank you!!
Love the Solution. Much cleaner than adding Gesturedetectors to every Scaffold
thanks