This tutorial shows you how to create a TextField
or TextFormField
that accepts only numbers.
It's quite common for an application to have an input field that accepts number only inputs. Flutter doesn't have a field widget that's dedicated for numeric value. However, you can use a TextField
or TextFormField
. There are some adjustments that you have to do in order to make it accepts number only values.
Set Keyboard Type to Number
If a field only accepts number values, it would be better to show a keyboard with related keys only. Non-related keys such as alphabetic characters and symbols other than -
, ,
and .
should not be displayed to users. Ideally, it should show a numeric pad. By showing the appropriate keyboard, users can type faster and more conveniently. In addition, it also prevents the users from typing unwanted characters.
To set the keyboard type, you can pass the keyboardType
argument and set the value to TextInputType.number
, which is a static constant for creating TextInputType
optimized for numerical information. Below is the example on a TextField
TextField(
keyboardType: TextInputType.number,
// other arguments
)
The usage for the TextFormField
is very similar.
TextFormField(
keyboardType: TextInputType.number,
// other arguments
)
There is also a const
constructor numberWithOptions
that allows you to specify whether the keyboard type should allow signed and decimal numbers.
const TextInputType.numberWithOptions({
bool signed = false,
bool decimal = false,
})
If you want the keyboard to support inputting signed numbers, you can set the signed
argument to true. To allow inputting decimal values, set the decimal
argument to true.
TextField(
keyboardType: const TextInputType.numberWithOptions(
signed: true,
decimal: true,
),
// other arguments
)
Using TextInputType.number
is actually the same as using TextInputType.numberWithOptions
without passing any argument which means both signed
and decimal
values are set to true.
However, even if the signed
and decimal
values are set to false, the -
and .
(or ,
depending on the locale) keys are still displayed on many devices. In addition, setting the keyboard type only affects what keys are shown to the users. It doesn't restrict or sanitize the value on the input field. That means the users can paste a non-numeric value to the field. To handle that, we need to filter the input which is going to be explained in the next section.
Format Numeric Input
For each TextField
or TextFormField
, Flutter allows you to add some TextInputFormatter
s by passing them as the inputFormatters
argument. A TextInputFormatter
can be used to provide validation and formatting when a field is being edited. It's invoked every time the text on the field changes. The TextInputFormatter
has a constructor named allow
which creates the formatter using a pattern. You can utilize it for sanitizing the value. If the new value contains an unwanted character or doesn't comply with a given pattern, just ignore the update and keep the old value.
Unsigned Integer Numbers
For unsigned integers, the only allowed characters are digits. For this case, you can use FilteringTextInputFormatter.digitsOnly
, which is a static variable that uses RegExp(r'[0-9]')
pattern.
TextField(
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
// other arguments
)
Output:
Unsigned Double Numbers
For unsigned doubles (numbers with decimal point), you can use the below regex. It accepts a string started with one or more digits, followed by an optional decimal point, and followed by zero or more digits.
TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*')),
],
// other arguments
)
Output:
It's also possible to limit the number of digits after the decimal point by adding the limit in the pattern.
TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
],
// other arguments
)
Output:
Signed Integer Numbers
For signed integers, the regex should include an optional -
at the start, followed by the digits.
TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'^\-?\d*')),
],
// other arguments
)
Output:
Signed Double Numbers
For signed doubles, the regex should include an optional -
at the start. Then, it's followed by the same regex used for signed decimal numbers which must be set to optional because in many cases the users will only input the -
sign at first. Below is the example where the number of decimal places is not limited.
TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'^\-?(\d+\.?\d*)?')),
],
// other arguments
)
Output:
Below is the example for signed doubles where the number of decimal places is limited.
TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'^\-?(\d+\.?\d{0,2})?')),
],
// other arguments
)
Output:
Summary
To create a TextField
or a TextFormField
that accepts numbers only, first you should set the keyboard type to display a numeric pad. In addition, you have to use a TextInputFormatter
for validating that the input value matches a certain pattern. This tutorial provides the patterns to use for unsigned and signed integer and double numbers.
You can also read about: