Shortcut Keyboard For TextField Widget

In this post, we will add a shortcut keyboard for TextField widget in Flutter app. This post is part of our building Expense Manager app series.

Introduction

Let’s say you have a user input field where users type in certain data. If user has to type a certain word or character frequently, you might want to provide a shortcut to such texts.

For an example, users might have to frequently type in numbers such as 100, 200, 500 etc. on a TextField. In this post, we will learn to create a shortcut keyboard just for that purpose.

DecisionMentor app

We are going to add this feature on our Expense Manager app continuing from previous post. At the end of this post, we will have achieved the following:

Shortcut Keyboard For TextField In Flutter
Shortcut Keyboard For TextField In Flutter

Setup

Adding A TextField For Numbers Input

In the add_expense.dart file below the category selector, add a Column widget. Inside it’s children we first add a TextField that allows users to enter numbers.

TextField For Amount
TextField For Amount

Create A Shortcut Keyboard Widget

Next, we create a shortcut keyboard Widget.

Widget _shortcutKeyboard() {
var keyboardKeys = [
  "50",
  "100",
  "500",
  "1000",
];
return Container(
	height: 53.0,
	decoration: BoxDecoration(
	  color: Theme.of(context).primaryColor,
	),
	child: ListView.builder(
	  scrollDirection: Axis.horizontal,
	  itemCount: keyboardKeys.length,
	  itemBuilder: (_, index) {
		var key = keyboardKeys[index];
		return Container(
		  padding: EdgeInsets.symmetric(horizontal: 6.0),
		  decoration: BoxDecoration(
			  borderRadius: BorderRadius.circular(8.0),
			  border: Border.all(color: Theme.of(context).accentColor)
			  ),
		  child: FlatButton(
			onPressed: null,
			child: Text(key),
		  ),
		);
	  },
	));
}

Here, we have created a horizontally scrollable ListView that has a list of FlatButton widgets for different numbers.

Now, add this widget below the previous TextField.

...
Column(
	children: <Widget>[
	  Container(
		padding:
			EdgeInsets.symmetric(vertical: 12.0, horizontal: 12.0),
		child: TextField(
			keyboardType: TextInputType.number,
			decoration: InputDecoration(
			  labelText: "Amount",
			),
			maxLines: 1,
			onChanged: (String text) {}),
	  ),
	  _shortcutKeyboard()
	],
  ),
...
Shortcut Keyboard Widget 1
Shortcut Keyboard Widget 1

A shortcut keyboard widget is created below our TextField.

However, there are still a few of issues that we want to take care of here:

  • Show shortcut keyboard right on top of device keyboard.
  • Show shortcut keyboard only when TextField is in focus.
  • Handle Shortcut key press event.

Position Shortcut Keyboard On Top Of Keyboard

In order to make sure our shortcut keyboard shows right on top of regular keyboard, we will make use of Expanded widget.

...
Expanded(
  child: Column(
children: <Widget>[
  Expanded(
	  child: Container(
	padding:
		EdgeInsets.symmetric(vertical: 12.0, horizontal: 12.0),
	child: TextField(
		keyboardType: TextInputType.number,
		decoration: InputDecoration(
		  labelText: "Amount",
		),
		maxLines: 1,
		onChanged: (String text) {}),
  )),
  _shortcutKeyboard()
],
...

Here we have wrapped both the Column and TextField container in Expanded widgets.

Check If TextField Is In Focus

Now, we need to check if our TextField is in focus before showing this shortcut keyboard. For this, we will make use of the FocusNode which will enable us to obtain the keyboard focus on TextField widget.

Create a FocusNode and add a listener to the focus change event.

...
class _AddExpenseState extends State<AddExpense> {
  CategoryBloc categoryBloc;
  FocusNode _focus = new FocusNode();
  bool _showKeyboard = false;

  @override
  void initState() {
    super.initState();
    categoryBloc = CategoryBloc(CategoryService());
    _focus.addListener(_onFocusChange);
  }

  void _onFocusChange() {
    setState(() {
     _showKeyboard = _focus.hasFocus; 
    });
  }
...
...
child: TextField(
       focusNode: _focus,
...

Here, we have created a FocusNode and assigned it to the TextField‘s focusNode property. Then we set the value of _showKeyboard to true when the TextField has focus.

Handle Keyboard Shortcut Key Press

Finally, we need to implement the short cut key press events. For this, first add a TextEditingController for the TextField.

...
TextEditingController _amountTextController = TextEditingController();
...
child: TextField(
	controller: _amountTextController,
	focusNode: _focus,
	keyboardType: TextInputType.number,
	decoration: InputDecoration(
...

Update the onPressed event for short key button.

child: FlatButton(
onPressed: () {
  setState(() {
	_amountTextController.text = key;
  });
},
Working Shortcut Keyboard
Working Shortcut Keyboard

Great, we now have a working shortcut keyboard for our TextField widget.

Update Keyboard Cursor Position Of TextField

As you might have noticed from the image above, although the text in the TextField is being updated, the cursor position isn’t correct. The cursor should move to the end of line. But it is staying at the beginning position of the text inside the TextField.

In order to fix this, we need to reset the values of TextSelection property of the TextEditingController.

_amountTextController.value = _amountTextController.value.copyWith(
  text: key,
  selection: TextSelection.collapsed(offset: key.length),
);

Here, we ensure that the selection is set to the last position of the text.

Conclusion

In this post, we learned to create a shortcut keyboard for TextField widget in flutter. The shortcut keyboard was made visible only when the TextField was set in focus. It was positioned on top of the device keyboard. Then the TextField‘s value was updated on the shortcut key press. We also learned to set the cursor position of TextField programmatically.

Learn More About Working With TextField Widget