I'm unable to find a way to create an input field in Flutter that would open up a numeric keyboard and should take numeric input only. Is this possible with Flutter material widgets? Some GitHub discussions seem to indicate this is a supported feature but I'm unable to find any documentation about it.
28 Answers
You can specify the number as keyboardType for the TextField using:
keyboardType: TextInputType.number
Check my main.dart file
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
home: new HomePage(),
theme: new ThemeData(primarySwatch: Colors.blue),
);
}
}
class HomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.white,
body: new Container(
padding: const EdgeInsets.all(40.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TextField(
decoration: new InputDecoration(labelText: "Enter your number"),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
], // Only numbers can be entered
),
],
),
),
);
}
}
-
28But I can paste the Texts (Characters) on that field do you have any other options? @Rissmon Suresh Jan 8, 2019 at 12:08
-
15
-
2
-
22inputFormatters: [WhitelistingTextInputFormatter.digitsOnly] is also required here ,as comma and dot can still be accepted here in the answer. Jun 28, 2020 at 10:08
-
31Deprecated: inputFormatters: [WhitelistingTextInputFormatter.digitsOnly]. Instead use: inputFormatters: [FilteringTextInputFormatter.digitsOnly]– ErenJul 30, 2021 at 3:47
For those who are looking for making TextField
or TextFormField
accept only numbers as input, try this code block :
for flutter 1.20 or newer versions
TextFormField(
controller: _controller,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
// for below version 2 use this
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
// for version 2 and greater youcan also use this
FilteringTextInputFormatter.digitsOnly
],
decoration: InputDecoration(
labelText: "whatever you want",
hintText: "whatever you want",
icon: Icon(Icons.phone_iphone)
)
)
for earlier versions of 1.20
TextFormField(
controller: _controller,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
decoration: InputDecoration(
labelText:"whatever you want",
hintText: "whatever you want",
icon: Icon(Icons.phone_iphone)
)
)
Note: You need to import services.dart
when using FilteringTextInputFormatter
import 'package:flutter/services.dart';
-
8This is welcome to avoid the user to paste non digit strings (inputFormatters), thanks. Aug 21, 2019 at 13:36
-
7This works well even in Flutter_web as well. The reason being in in flutter_web we cannot enforce a numeric keyboard so restriction is the natural option. Thanks @BilalŞimşek Sep 4, 2019 at 15:23
-
2
-
3I work with flutter 2.1.0, This still works as well.
inputFormatters: <TextInputFormatter>[ WhitelistingTextInputFormatter.digitsOnly ],
– SilkeNLApr 14, 2021 at 9:25 -
4WhitelistingTextInputFormatter.digitsOnly is deprecated in Flutter 2.2.2, instead use inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly] to allow digits only (no commas, spaces, or # are allowed)– M. A.Jun 22, 2021 at 10:03
Through this option you can strictly restricted another char with out number.
inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
keyboardType: TextInputType.number,
For using above option you have to import this
import 'package:flutter/services.dart';
using this kind of option user can not paste char in a textfield
-
3if i want just decimal and digits. how do add the "." into the whitelist of formatter? Jul 19, 2020 at 5:44
-
7@anoop4real yes i just use TextFormField( keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.allow((RegExp("[.0-9]"))) ], ) There is a "." in the regExp Dec 9, 2020 at 6:04
-
2@shababhsiddique it allows for multiple "."s . i want to accept double numbers. any idea how? Feb 18, 2021 at 11:20
-
3
-
1WhitelistingTextInputFormatter is depricated change to FilteringTextInputFormatter stackoverflow.com/a/70335837/9576680– DidierMay 6, 2022 at 10:57
Set the keyboard and a validator
String numberValidator(String value) {
if(value == null) {
return null;
}
final n = num.tryParse(value);
if(n == null) {
return '"$value" is not a valid number';
}
return null;
}
new TextFormField(
keyboardType: TextInputType.number,
validator: numberValidator,
textAlign: TextAlign.right
...
-
Got error: Local variable num cannot be referenced before it is declared– kashloJan 10, 2019 at 13:42
-
Ok, the name
num
for the variable does not work. The name needs to be changed Jan 10, 2019 at 13:49 -
1From docs: The onError parameter is deprecated and will be removed. Instead of num.parse(string, (string) { ... }), you should use num.tryParse(string) ?? (...).– kashloJan 10, 2019 at 15:02
To avoid paste not digit value, add after
keyboardType: TextInputType.number
this code :
inputFormatters: [FilteringTextInputFormatter.digitsOnly]
from https://api.flutter.dev/flutter/services/FilteringTextInputFormatter-class.html
For those who need to work with money format in the text fields:
To use only: , (comma) and . (period)
and block the symbol: - (hyphen, minus or dash)
as well as the: ⌴ (blank space)
In your TextField, just set the following code:
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [BlacklistingTextInputFormatter(new RegExp('[\\-|\\ ]'))],
The simbols hyphen and space will still appear in the keyboard, but will become blocked.
-
1
-
1@HeddieFranco read about regex developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/… Dec 5, 2019 at 12:05
If you need to use a double number:
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp('[0-9.,]')),],
onChanged: (value) => doubleVar = double.parse(value),
RegExp('[0-9.,]')
allows for digits between 0 and 9, also comma and dot.
RegExp('[0-9.,-]')
allows for digits between 0 and 9, also comma, dot and minus sign (for negative numbers).
double.parse()
converts from string to double.
Don't forget you need:
import 'package:flutter/services.dart';
You can check and test a full demo at this dartpad
If you want to allow minus sign only at the start of the string:
final RegExp _myPattern = RegExp(r'^-?[\d,.]*$');
(...)
TextInputFormatter.withFunction(
(TextEditingValue oldValue, TextEditingValue newValue) {
return _myPattern.hasMatch(newValue.text)
? newValue
: oldValue;
},
),
You can check and test the full demo2 at this other dartpad
-
-
-
with [0-9.,-] you can insert the '-' sign at any position (e.g. 12-34.01). should be something like: ^-?[0-9.,] but this regex expression is not working as I would expect– cabbiOct 17, 2023 at 11:15
-
"FilteringTextInputFormatter typically shouldn't be used with RegExps that contain positional matchers (^ or $) " api.flutter.dev/flutter/services/… Oct 17, 2023 at 16:12
-
1@cabbi I've updated the answer with an option to allow minus sign only at the start of the string Oct 18, 2023 at 16:48
The TextField
widget is required to set keyboardType: TextInputType.number,
and inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly]
to accept numbers only as input.
TextField(
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
], // Only numbers can be entered
),
Example in DartPad
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
theme: ThemeData(primarySwatch: Colors.blue),
);
}
}
class HomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return HomePageState();
}
}
class HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Container(
padding: const EdgeInsets.all(40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("This Input accepts Numbers only"),
SizedBox(height: 20),
TextField(
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.greenAccent, width: 5.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 5.0),
),
hintText: 'Mobile Number',
),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
], // Only numbers can be entered
),
SizedBox(height: 20),
Text("You can test be Typing"),
],
)),
);
}
}
You can use this two attributes together with TextFormField
TextFormField(
keyboardType: TextInputType.number
inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
It's allow to put only numbers, no thing else ..
https://api.flutter.dev/flutter/services/TextInputFormatter-class.html
As the accepted answer states, specifying keyboardType
triggers a numeric keyboard:
keyboardType: TextInputType.number
Other good answers have pointed out that a simple regex-based formatter can be used to allow only whole numbers to be typed:
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
The problem with this is that the regex only matches one symbol at a time, so limiting the number of decimal points (e.g.) cannot be achieved this way.
Also, others have also shown that if one wants validation for a decimal number, it can be achieved by using a TextFormField
and it's validator
parameter:
new TextFormField(
keyboardType: TextInputType.number,
validator: (v) => num.tryParse(v) == null ? "invalid number" : null,
...
The problem with this is that it cannot be achieved interactively, but only at form submission time.
I wanted to allow only decimal numbers to be typed, rather than validated later. My solution is to write a custom formatter leveraging int.tryParse
:
/// Allows only decimal numbers to be input.
class DecimalNumberFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
// Allow empty input and delegate formatting decision to `num.tryParse`.
return newValue.text != '' && num.tryParse(newValue.text) == null
? oldValue
: newValue;
}
}
Alternatively, one can use a regex for the custom formatter, which would apply to the whole input, not just a single symbol:
/// Allows only decimal numbers to be input. Limits decimal plates to 3.
class DecimalNumberFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
// Allow empty input.
if (newValue.text == '') return newValue;
// Regex: can start with zero or more digits, maybe followed by a decimal
// point, followed by zero, one, two, or three digits.
return RegExp('^\\d*\\.?\\d?\\d?\\d?\$').hasMatch(newValue.text)
? newValue
: oldValue;
}
}
This way, I can also limit the number of decimal plates to 3.
Here is code for actual Phone keyboard on Android:
Key part: keyboardType: TextInputType.phone,
TextFormField(
style: TextStyle(
fontSize: 24
),
controller: _phoneNumberController,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
prefixText: "+1 ",
labelText: 'Phone number'),
validator: (String value) {
if (value.isEmpty) {
return 'Phone number (+x xxx-xxx-xxxx)';
}
return null;
},
),
Number type only
keyboardType: TextInputType.number
And more option with number pad
keyboardType: TextInputType.numberWithOptions(decimal: true,signed: false)
Just add this to your TextFormField
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), ],
Example,
TextFormField(
controller: textController,
onChanged: (value) {
print(value);
},
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
),
To Create number input field, You just need to give following property inside your textfield or textformfield.
TextField(
keyboardType: TextInputType.number, // Set the keyboard type to number
decoration: InputDecoration(
hintText: 'Enter a number',
),
);
Happy Fluttering!
You can Easily change the Input Type using the keyboardType Parameter and you have a lot of possibilities check the documentation TextInputType so you can use the number or phone value
new TextField(keyboardType: TextInputType.number)
You can try this:
TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
prefixIcon: Text("Enter your number: ")
),
initialValue: "5",
onSaved: (input) => _value = num.tryParse(input),
),
keyboardType: TextInputType.number
would open a num pad on focus, I would clear the text field when the user enters/past anything else.
keyboardType: TextInputType.number,
onChanged: (String newVal) {
if(!isNumber(newVal)) {
editingController.clear();
}
}
// Function to validate the number
bool isNumber(String value) {
if(value == null) {
return true;
}
final n = num.tryParse(value);
return n!= null;
}
For number input or numeric keyboard you can use keyboardType: TextInputType.number
TextFormField(
decoration: InputDecoration(labelText:'Amount'),
controller: TextEditingController(
),
validator: (value) {
if (value.isEmpty) {
return 'Enter Amount';
}
},
keyboardType: TextInputType.number
)
You can add input format with keyboard type, like this
TextField(
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],// Only numbers can be entered
keyboardType: TextInputType.number,
);
I need en IntegerFormField with a controll of min/max. And the big problem is that OnEditingComlete is not called when the focus changes. Here is my solution:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:vs_dart/vs_dart.dart';
class IntegerFormField extends StatefulWidget {
final int value, min, max;
final InputDecoration decoration;
final ValueChanged<TextEditingController> onEditingComplete;
IntegerFormField({@required this.value, InputDecoration decoration, onEditingComplete, int min, int max})
: min = min ?? 0,
max = max ?? maxIntValue,
onEditingComplete = onEditingComplete ?? ((_) {}),
decoration = decoration ?? InputDecoration()
;
@override
_State createState() => _State();
}
class _State extends State<IntegerFormField> {
final TextEditingController controller = TextEditingController();
@override
void initState() {
super.initState();
controller.text = widget.value.toString();
}
@override
void dispose() {
super.dispose();
}
void onEditingComplete() {
{
try {
if (int.parse(controller.text) < widget.min)
controller.text = widget.min.toString();
else if (int.parse(controller.text) > widget.max)
controller.text = widget.max.toString();
else
FocusScope.of(context).unfocus();
} catch (e) {
controller.text = widget.value.toString();
}
widget.onEditingComplete(controller);
}
}
@override
Widget build(BuildContext context) {
return Focus(
child: TextFormField(
controller: controller,
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
keyboardType: TextInputType.number,
decoration: widget.decoration,
),
onFocusChange: (value) {
if (value)
controller.selection = TextSelection(baseOffset: 0, extentOffset: controller.value.text.length);
else
onEditingComplete();
},
);
}
}
Set your keyboardType to TextInputType.number,
Eg: keyboardType: TextInputType.number,
TextFormField(
controller: yourcontroller,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'Mobile',
suffixIcon: Padding(
padding: EdgeInsets.only(),
child:
Icon(Icons.phone_outlined, color: Color(0xffff4876)),
),
),
validator: (text) {
if (text == null || text.isEmpty) {
return 'Please enter your Mobile No.';
}
return null;
},
),
U can Install package intl_phone_number_input
dependencies:
intl_phone_number_input: ^0.5.2+2
and try this code:
import 'package:flutter/material.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var darkTheme = ThemeData.dark().copyWith(primaryColor: Colors.blue);
return MaterialApp(
title: 'Demo',
themeMode: ThemeMode.dark,
darkTheme: darkTheme,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: Text('Demo')),
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
final TextEditingController controller = TextEditingController();
String initialCountry = 'NG';
PhoneNumber number = PhoneNumber(isoCode: 'NG');
@override
Widget build(BuildContext context) {
return Form(
key: formKey,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InternationalPhoneNumberInput(
onInputChanged: (PhoneNumber number) {
print(number.phoneNumber);
},
onInputValidated: (bool value) {
print(value);
},
selectorConfig: SelectorConfig(
selectorType: PhoneInputSelectorType.BOTTOM_SHEET,
backgroundColor: Colors.black,
),
ignoreBlank: false,
autoValidateMode: AutovalidateMode.disabled,
selectorTextStyle: TextStyle(color: Colors.black),
initialValue: number,
textFieldController: controller,
inputBorder: OutlineInputBorder(),
),
RaisedButton(
onPressed: () {
formKey.currentState.validate();
},
child: Text('Validate'),
),
RaisedButton(
onPressed: () {
getPhoneNumber('+15417543010');
},
child: Text('Update'),
),
],
),
),
);
}
void getPhoneNumber(String phoneNumber) async {
PhoneNumber number =
await PhoneNumber.getRegionInfoFromPhoneNumber(phoneNumber, 'US');
setState(() {
this.number = number;
});
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}
Here is code for numeric keyboard : keyboardType: TextInputType.phone When you add this code in textfield it will open numeric keyboard.
final _mobileFocus = new FocusNode();
final _mobile = TextEditingController();
TextFormField(
controller: _mobile,
focusNode: _mobileFocus,
maxLength: 10,
keyboardType: TextInputType.phone,
decoration: new InputDecoration(
counterText: "",
counterStyle: TextStyle(fontSize: 0),
hintText: "Mobile",
border: InputBorder.none,
hintStyle: TextStyle(
color: Colors.black,
fontSize: 15.0.
),
),
style: new TextStyle(
color: Colors.black,
fontSize: 15.0,
),
);
Here is code for actual Phone keyboard in Flutter:
//Mobile
const TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
prefixIcon: Icon(Icons.phone), hintText: 'Mobile'),
),
Here are all details on how to add numeric keybord, How to do validations, How to add stylings, and other stuff in dart/flutter. I hope it can help you to learn in a better way.
Padding(
padding: const EdgeInsets.all(3.0),
child: TextFormField(
maxLength: 10,
keyboardType: TextInputType.number,
validator: (value) {
if (value.isEmpty) {
return 'Enter Number Please';
}
return null;
},
decoration: InputDecoration(
prefixIcon: Icon(Icons.smartphone),
prefixText: '+92',
labelText: 'Enter Phone Number',
contentPadding: EdgeInsets.zero,
enabledBorder: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2, color: Theme
.of(context)
.primaryColor,
)
),
focusColor: Theme
.of(context)
.primaryColor,
),
),
),
TextField(
controller: _controller,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0.0-9.9]')),
])
For anyone who wants to allow phone number that starts with + (plus) sign. Try this
TextFormField(
controller: controller,
/// Add this
keyboardType: TextInputType.numberWithOptions(decimal: true, signed: true),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\+?\d*'))],
///
),
you can use this plugin it's very easy with this plugin
enter code here
link: https://pub.dev/packages/intl_phone_number_input/example