Custom In-App Keyboard in Flutter

Tram Ho

This article will guide you on how to create a custom keyboard for typing in your own application. Use cases include entering text for special characters or languages ​​in which the system keyboard might not exist or the user might not have the correct keyboard installed. For example, I used this method with the mongol package to create a basic keyboard for entering traditional Mongolian text:

Today we will create a simpler version:

Note: This article won’t tell you how to build a system keyboard that users install and can use in any application. This is just a widget-based approach to use in your own app. The full code is at the bottom of the article. It’s updated for Flutter 1.22 and Dart 2.10.

1. Create widget key

Flutter can easily create complex keyboard layouts by incorporating simpler widgets. So to get started, you’ll create a few simple main widgets.

1.1 Text key

I have circled the keys generated from the TextKey utility that you will create first.

Add this TextKey widget to your project:

Here’s the cool part: The flex property allows your keys to be evenly distributed across a row or even take up a larger proportion of a row (like the space key in the image above). When the key is pressed, it passes its value onto the keyboard as an onTextInput callback.

1.2 Backspace key

You also need a delete key that looks and functions differently from the TextKey utility.

Note: There is a bit of overlap with the TextKey code, so some refactoring will make it DRY, especially if you add other key types like shift. However, it is allowed for learning purposes today. onBackspace is a VoidCallback because there is no need to convert any text back to the keyboard.

1.3 Organize the keys into a keyboard

The keyboards are easy to layout when you have the keys because they are just rows in a column.

Here is the code. I omit some repetitions for brevity. However, you can find them all at the end of the article.

The keyboard collects the callbacks from the keys and transfers them to the interface. That way, anyone using CustomKeyboard will get a callback. You can see how flex is used in the third row. The space key has a flexibility of 4 while the backspace key retains the default flexibility of 1. That makes the space key four times the width of the backspace key.

1.4 Handling text input

Controller is TextE EditorController for TextField. You must remember that there may be an option, so if so, replace it with the text that the key was passed on.

1.5 Handling backspace

You think the backspace will be simple, but there are a few different cases to think about: There is a choice (delete selection) Cursor at the top (do nothing) Everything else (delete previous character) Here is the implementation of the _backspace method:

Even deleting the previous character is a bit difficult. If you only undo a code unit when you have emojis or some other alternate pair (see Working with Unicode and Grapheme Clusters in Dart), this will cause an error. As another workaround in the above code, I checked if the previous character is the UFT-16 alternate character and if so then the space between the two characters. (I got the isUtf16Surrogate method from the Flutter TextPainter source code.) However, this is still not a perfect solution as it will not work for grapheme clusters like ?? or ?‍?‍?, generated into words more than a single surrogate pair. However, at least it won’t cause a problem. Here is a pictogram keyboard and emojis as a demonstration:

1.5 Prevent the system keyboard from showing

It will be very annoying if you want to use your custom keyboard with TextField but the system keyboard keeps popping up. That is the default behavior. The way to prevent the system keyboard from displaying is to set the readOnly property of TextField to true.

1.6 Switch between the system keyboard and your keyboard

If you want to give the user the option of using your system keyboard or custom keyboard, you can simply recreate it with a different value for readOnly.

Here’s how TextField is set up in the demo application:

When IconButton is pressed on the keyboard, the value of _readOnly is changed and the layout is then rebuilt. This makes the system keyboard invisible or visible. Setting resizeToAvoidBottomInset on Scaffold to false allows the system keyboard to mask the custom keyboard. Another option is to hide the custom keyboard while the system keyboard is showing. However, when I did that in my tests, I found that I had to use a separate boolean to hide the custom keyboard so I could delay displaying it until the system keyboard disappeared. If not, it will jump to the top of the system keyboard in an instant. That’s it! As you can see, it’s not too difficult to create your own in-app keyboard.

1.7 Full code

Share the news now

Source : Viblo