Murtaza Sulaihi I am a school professor and I also develop Android applications and Flutter applications.

How to open or dismiss the keyboard in Flutter

4 min read 1189

How To Open Or Dismiss The Keyboard In Flutter

Do you miss Blackberry phones? I do. They had a full QWERTY keyboard, and it was so easy to type. I wish they had evolved with time, with the operating system. We would be seeing some great innovations with its physical keyboards and touch screen devices.

Blackerry Phone

Instead, we programmers and designers are confronted with a particular modern challenge: the soft keyboard. Mobile app developers must keep in mind that the keyboard on phones is constantly hidden from view.

As a result, the UI designer must be significantly more careful. When the keyboard appears, it should not obscure other sections of the UI while entering data into a specific widget.

Closing the keyboard: Buttons, taps, swipes?

Then there are various devices with diverse screen sizes. Consider two types of devices right now: iOS and Android. Android smartphones contain physical or soft buttons used to navigate the software. On iOS devices, closing or switching between applications is currently accomplished with a single swipe from the bottom to the top.

When it comes to keyboard management on both devices, tapping on a widget that allows data input opens the keyboard from the bottom of the screen. The real problem arises now on how to close the keyboard when not in use or give the user enough control over the keyboard opening and closing.

Android devices have a solution; press the physical back button (provided on some mobile phones) or the soft key back button, and it closes the keyboard. But what about the iOS devices? On iPhones, if the user swipes from the bottom towards the top, it will close the application entirely or switch between applications. On iPads, there is a button on the bottom right corner for minimizing the keyboard or closing the keyboard.

Opening and dismissing the keyboard with Flutter

Flutter being a multi-platform framework, how do we solve this problem of opening and closing the keyboard to be consistent with the application across all devices?

Based on my research and experience, I offer this solution for:

  1. Opening and closing the keyboard on both Android and iOS devices
  2. Conveniently move towards the next input widget without dismissing the keyboard

Some of the Flutter widgets that offer input of texts and numbers are:

  1. TextField
  2. TextFormField
  3. CupertinoSearchTextField
  4. CupertinoTextField

Calling or dismissing the keyboard on tap

The most common screens where a programmer would use these widgets are for login and signup screens. If the application requires filling a form with user data, there might be more text fields on that screen. Some might need only text input, and some only numbers or both. Tapping on these widgets will cause the keyboard to open.

If you create something similar to the above screen, you must remember that it will push the widget upward when the keyboard opens, causing an overflow error. To solve this, you need to wrap the widgets in a SingleChildScrollView or a ListView, depending on your UI.

When you wrap your widget with SingleChildScrollView or ListView, both widgets have a property called keyboardDismissBehavior. It represents how a ScrollView should dismiss the onscreen keyboard.

In addition, it has two types of drag behavior: a manual where it is up to the user to dismiss the keyboard, and onDrag where the keyboard gets dismissed when the user starts to drag on the screen.

Keyboard Dismissal When User Drags On The Screen

SingleChildScrollView(
 keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
 child: Padding(
   padding: const EdgeInsets.symmetric(
       vertical: Sizes.dimen_20, horizontal: Sizes.dimen_14),
   child: Column(
     children: [
       TextFormField(
         controller: _studentNameController,
         keyboardType: TextInputType.name,
         textCapitalization: TextCapitalization.words,
         textInputAction: TextInputAction.next,
         decoration:
   kTextInputDecoration.copyWith(labelText:'Student Name'), ),

Wrapping your whole view in a widget

Another method to dismiss the keyboard is to wrap your whole view, meaning the parent widget most commonly used is the Scaffold widget or SafeArea with the GestureDetector. Inside its onTap property, you have to pass an unfocus function, which removes the focus from the current node and moves its primary focus to another node.

To better understand when the keyboard is open, the primary focus is on the keyboard. When you click anywhere else on the screen, the GestureDetector removes the focus from the keyboard and shifts its primary focus on the view, which eventually closes the keyboard.



Keyboard Dismissal When User Drags On The Screen

@override
Widget build(BuildContext context) {
 return GestureDetector(
   //onTap: () => FocusScope.of(context).unfocus(),
   /// > flutter 2.0
   onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
   child: Scaffold(
     resizeToAvoidBottomInset: true,
     appBar: AppBar(
       title: const Text('Keyboard Open and Close'),     ),
     body: ListView(
       padding: const EdgeInsets.all(14.0),
       shrinkWrap: true,
       keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
       children: [
         TextFormField(
           controller: _studentNameController,
           keyboardType: TextInputType.name,
           textCapitalization: TextCapitalization.words,
           textInputAction: TextInputAction.next,
           decoration:
     kTextInputDecoration.copyWith(labelText: 'Student Name'),),

You might be wondering whether it is advisable to use the GestureDetector on the whole view. According to the documentation, it is safe to call regardless of whether the view ever requested focus or not.

However, nothing happens if it does have focus or primary focus. To fully understand this action, when the user clicks anywhere else on the screen beside the text field widget, nothing happens visually anywhere else on the screen except the closing of the keyboard.

Creating the Next button to move between fields

If you have more than one text field widget on any of your screens, the textInputAction property will help you a lot with user experience. Therefore, I advise you to pass (TextInputAction.next) for every text field.

Then, instead of the Enter button on the keyboard, you will see the Next button. When the user finishes entering data in the first text field, clicking on the Next button will directly take the user to the following text field widget without extra touch input. This action also prevents the keyboard from closing and opening when focus changes from one text field to another.

Keyboard Remains Despite When Focus Changes From One Text Field To Another

TextFormField(
 controller: _fatherNameController,
 keyboardType: TextInputType.name,
 textCapitalization: TextCapitalization.words,
 textInputAction: TextInputAction.next,
 decoration:
     kTextInputDecoration.copyWith(labelText: 'Father Name'),
),

Conclusion

User interface and user experience are inextricably linked. We should be more concerned with the user experience as programmers since it doesn’t matter how appealing the application looks if the user finds it difficult to interact with. Once the UX is solved, the UI will be an extra benefit to the overall application experience.

The mobile application’s user experience includes opening and closing the keyboard. When should it be opened? Should it open when the screen appears or when the user taps the screen? And when should the keyboard be closed? Is the keyboard obstructing something on the screen when it opens, such as the widget where the user wants to enter data?

There are so many things happening, and there are so many things to think about on a single screen just focusing on keyboard opening and closing.


More great articles from LogRocket:


There is always a problem, and I have written two possible solutions for opening and closing the soft keyboard on smartphones using the Flutter framework. Hopefully, you will be using those solutions for your next project, and if you come up with a better solution than I have provided, I would love to hear about it. I love discovering new things in Flutter, which requires a little bit of experimentation.

Thank you! Stay safe!

Get setup with LogRocket's modern error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID.
  2. Install LogRocket via NPM or script tag. LogRocket.init() must be called client-side, not server-side.
  3. $ npm i --save logrocket 

    // Code:

    import LogRocket from 'logrocket';
    LogRocket.init('app/id');
    Add to your HTML:

    <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
  4. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • ngrx middleware
    • Vuex plugin
Get started now
Murtaza Sulaihi I am a school professor and I also develop Android applications and Flutter applications.

Leave a Reply