Create custom textformfield - flutter

I am trying to create custom textformfield so I can easily style only in one place. But currently I am stuck on how to pass validation and save process. Can someone give me a working example of custom widget textformfield that I can use? I have been searching it for whole day and cannot find one. Thank you for help.
Example here is on raised button:
import 'package:flutter/material.dart';
import 'package:wkndr/resources/constants.dart';
class CustomButton extends StatelessWidget {
CustomButton({#required this.text, #required this.onPressed});
final String text;
final GestureTapCallback onPressed;
#override
Widget build(BuildContext context) {
return RaisedButton(
color: colorPrimary,
child: Text(text, style: TextStyle(fontSize: 17.0, color: colorWhite)),
onPressed: onPressed,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
);
}
}
Calling custom raised button:
final _signUpButton = Container(
child: CustomButton(
text: sign_up,
onPressed: () {
_signUp();
}),
);

Instead of making custom textformfield you can make common InputDecoration for styling
class CommonStyle{
static InputDecoration textFieldStyle({String labelTextStr="",String hintTextStr=""}) {return InputDecoration(
contentPadding: EdgeInsets.all(12),
labelText: labelTextStr,
hintText:hintTextStr,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
);}
}
Example:-
TextFormField(
controller: usernameController,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
focusNode: userFocus,
onFieldSubmitted: (_) {
FocusScope.of(context).requestFocus(passFocus);
},
validator: (value) => emptyValidation(value),
decoration: CommonStyle.textFieldStyle(labelTextStr:"Username",hintTextStr:"Enter Username"),
)

You can define InputDecorationTheme in your app theme to set global style for text fields.
MaterialApp(
title: title,
theme: ThemeData(
brightness: Brightness.dark,
...
inputDecorationTheme: InputDecorationTheme(
fillColor: Colors.blue,
filled: true,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white)),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
hintStyle: TextStyle(color: Colors.white.withAlpha(80)),
),
)
);
You can also change theme properties for a particular widget using Theme widget:
Theme(
data: Theme.of(context).copyWith(inputDecorationTheme: /*new decoration theme here*/),
child: Scaffold(
body: ...,
),
);
See more information about themes in Flutter docs.

You can try custom TextFormField.
You can make easily common TextFormField for customizing TextFormField.
You can try like this.
Step 1: First create one dart class i.e EditTextUtils
Step 2: Create a function or method i.e getCustomEditTextArea
class EditTextUtils {
TextFormField getCustomEditTextArea(
{String labelValue = "",
String hintValue = "",
bool validation,
TextEditingController controller,
TextInputType keyboardType = TextInputType.text,
TextStyle textStyle,
String validationErrorMsg}) {
TextFormField textFormField = TextFormField(
keyboardType: keyboardType,
style: textStyle,
controller: controller,
validator: (String value) {
if (validation) {
if (value.isEmpty) {
return validationErrorMsg;
}
}
},
decoration: InputDecoration(
labelText: labelValue,
hintText: hintValue,
labelStyle: textStyle,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5.0))),
);
return textFormField;
}
}
Example: You can try like this
EditTextUtils().getCustomEditTextArea(
labelValue: 'label',
hintValue: 'hint',
validation: true,
controller: controller_name,
keyboardType: TextInputType.number,
textStyle: textStyle,
validationErrorMsg: 'error_msg')

Related

TextFormField not resetting when exiting page

I made the TextFormField Widget to be able to use it wherever needed. The codes are as follows;
Widget TextFormFieldWidget(
TextEditingController controller,
Icon icon,
String hintText,
bool obscureText,
BuildContext context,
) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ThemeData().colorScheme.copyWith(
primary: Colors.red,
),
),
child: TextFormField(
obscureText: obscureText,
controller: controller,
decoration: InputDecoration(
hintText: hintText,
prefixIcon: icon,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: const BorderSide(
color: Color(0xFFCB3126),
),
),
),
),
);
}
I'm having a problem. Here's the problem: I'm making a registration page. When the user exits the page and enters back, the values ​​entered in the TextFormField are not reset. For example, let me give an example that the user gives up after entering their e-mail address. When you leave the page and enter back, the e-mail address is not deleted.
How can I solve the problem? Thanks for help.
Please clear the text controllers value when you exit the page.
Dispose the controller
Clear the Conroler.
ElevatedButton(
onPressed: (){
controller.clear();
},
child: Text("Send")
)
In case you use one (a shared) TextController an the one TextController gets passed in to each TextFormFieldWidget, the the single controller will have a single state.
Thus, it keeps its value when getting attached to a new TextFormFieldWidget.
Please use different TextEditingController for different fields.
The issue with creating a function to return a Widget is such. If you're making a custom widget for your app, let's say reusable custom text field, It is suggested to be made into a separate StatefulWidget.
When you use stateful widget, you make a new instance of the same widget as per needed.
Use the below mentioned code to create the same for yours.
import "package:flutter/material.dart";
class CustomTextFormField extends StatefulWidget {
const CustomTextFormField(
{required this.icon,
required this.hintText,
required this.obscureText,
super.key});
final Icon icon;
final String hintText;
final bool obscureText;
#override
State<CustomTextFormField> createState() => _CustomTextFormFieldState();
}
class _CustomTextFormFieldState extends State<CustomTextFormField> {
late TextEditingController controller;
#override
void initState() {
controller = TextEditingController();
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ThemeData().colorScheme.copyWith(
primary: Colors.red,
),
),
child: TextFormField(
obscureText: widget.obscureText,
controller: controller,
decoration: InputDecoration(
hintText: widget.hintText,
prefixIcon: widget.icon,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: const BorderSide(
color: Color(0xFFCB3126),
),
),
),
),
);
}
}

How can i change TextField on hover in flutter?

Hi i'm trying to change the background color of my TextField Widget in flutter when the user focus on it. But it kinda seems there is no way to do it. If anybody has any idea please let me know ^^.
Here's the Widget itself:
TextField(
controller: emailController,
style: TextStyle(
color: Colors.white, fontSize: 18, height: 0.8),
textAlign: TextAlign.center,
decoration: InputDecoration(
focusColor: AppColors.inputBackgroundDarkFocus,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Color(color)),
),
filled: true,
fillColor: Color(0xff25282C),
hintText: 'Email',
hintStyle:
TextStyle(fontSize: 18, color: Colors.white),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
Thks <3
Hover & focus are two different things, so this might not answer your question, but the below can change field color "on focus" (the cursor is in the field).
If you're implementing purely for Flutter web and you want to handle "hover" you could do the below with a MouseRegion wrapper instead of Focus. Info on MouseRegion.
By wrapping a form field in a Focus widget, you can listen/capture focus changes on that field using the onFocusChange constructor argument (of Focus).
It takes a Function(bool).
Here's an example of an onFocusChange handler function:
onFocusChange: (hasFocus) {
if (hasFocus) {
print('Name GAINED focus');
setState(() {
bgColor = Colors.purple.withOpacity(.2);
});
}
else {
print('Name LOST focus');
setState(() {
bgColor = Colors.white;
});
}
},
If you wrap your field in a Container, you can give the Container a color and change that color using a Focus widget described above.
Here's a full page example (stolen from another answer of mine on a similar topic):
import 'package:flutter/material.dart';
class TextFieldFocusPage extends StatefulWidget {
#override
_TextFieldFocusPageState createState() => _TextFieldFocusPageState();
}
class _TextFieldFocusPageState extends State<TextFieldFocusPage> {
Color bgColor = Colors.white;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// ↓ Add this wrapper
Focus(
child: Container(
color: bgColor,
child: TextField(
autofocus: true,
decoration: InputDecoration(
labelText: 'Name'
),
textInputAction: TextInputAction.next,
// ↓ Handle focus change via Software keyboard "next" button
onEditingComplete: () {
print('Name editing complete');
FocusScope.of(context).nextFocus();
},
),
),
canRequestFocus: false,
// ↓ Focus widget handler, change color here
onFocusChange: (hasFocus) {
if (hasFocus) {
print('Name GAINED focus');
setState(() {
bgColor = Colors.purple.withOpacity(.2);
});
}
else {
print('Name LOST focus');
setState(() {
bgColor = Colors.white;
});
}
},
),
TextField(
decoration: InputDecoration(
labelText: 'Password'
),
),
],
),
),
),
);
}
}
I think you can repeat this for each field you need colored.
Hovering can be managed using the hoverColor property of InputDecoration:
Full source code:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Hover TextField Demo',
home: HomePage(),
),
);
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: TextField(
decoration: InputDecoration(
filled: true,
hoverColor: Colors.indigo.shade200,
hintText: 'Email',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
),
);
}
}
Almost every style property can be changed by decoration property, which requires an InputDecoration object.
To handle the hover style, this object provides only the hoverColor property, which overwrite the filledColor when the mouse is hovering the widget. The filled property needs to be true for this to work.
InputDecoration(
filled: true,
hoverColor: Colors.red,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
The problem is when you want to change others style properties like the border for example.
In that case you need to make your widget Statefull and add a state boolean like isHover.
Then you could wrap your widget inside MouseRegion and handle the hovering like in this example:
return MouseRegion(
onEnter: (_)=>setState(()=>isHover = true),
onExit: (_)=>setState(()=>isHover = false),
child: YourWidget(),
);
Once isHover is available you can use wherever you want to change the UI according to the hover state.
Example with border:
TextField(
decoration: InputDecoration(
filled: true,
hoverColor: Colors.red,
border: isHover? OutlineInputBorder(
borderSide: BorderSide(
color: Colors.green,
width: 1.5,
),
borderRadius: BorderRadius.circular(8.0),
) : null,
//By leaving null, the component will use the default value
),
),
I think the limitation is due to the fact that the hover behaviour is more web/desktop related. I hope flutter is going to implement better properties to handle this inside InputDecoration.

how to enable/disable button depends only on one textfield using streams in flutter

I am trying to disable/enable button in flutter that depends only on one textfield, I use streams. I have no idea how to do it. I have done it before but I cant remember how I made it. here is a code.
code of TextField:
TextField(
controller: balanceFieldText,
onChanged: name == KOREK ? bloc.korekSink : bloc.asiaSink,
keyboardType: TextInputType.number,
decoration: InputDecoration(
errorText: snapshot.error,
errorStyle: TextStyle(color: Colors.amber),
enabledBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(20.5),
),
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.red[900],
style: BorderStyle.solid,
width: 2)),
fillColor: Colors.white,
filled: true,
prefixIcon: IconButton(
icon: Icon(
Icons.camera_alt,
color: Colors.grey,
),
onPressed: () {
print('sdfgsg');
},
),
suffixIcon: IconButton(
icon: Icon(
Icons.keyboard_voice,
color: Colors.grey,
),
onPressed: () {
print('adfaf');
}),
labelText: 'ژمارەی کارت',
labelStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w300,
),
hintText: 'ژمارەی سەر کارتەکە وەك خۆی بنوسەوە',
hintStyle: TextStyle(color: Colors.grey, fontSize: 12.5),
),
);
}),
and here is code of my button:
RaisedButton(
child: Text('پڕبکەوە'),
onPressed: /* how to check it here to make button enable if textfield has no error */ null,
);
I want it to enable button anytime textfield is valid.
I don't know this can solve for your problem....
if you choose my solution you need to update your pubspec.yaml importing library of rxdart and provider. in the bloc.dart:
class Bloc extends Object with Validators{
final Behavior<String> _checkText = Behavior<String>();
Observable<String> get checkText => _checkText.stream.transform(validateText);// the transform is used to check whenever there is some changed in your textfield and done some validation
Function(String) get checkTextOnChanged => _checkText.sink.add;
}
in the validators.dart:
class Validators {
final StreamTransformer<String, String> validateText =
StreamTransformer<String, String>.fromHandlers(
handleData: (String text, EventSink<String> sink) {
// Sample of checking text pattern
const Pattern pattern = r'^[0-9]*$';
final RegExp regex = RegExp(pattern);
if (text != null) {
if (!regex.hasMatch(text)) {
sink.add(null);
sink.addError('text only accept number!');
} else {
sink.add(text);
}
}
});
}
in your screen.dart:
final Bloc bloc = Provider.of<Bloc>();
TextField(
.....
onChanged: bloc.checkText,
.....
);
StreamBuilder(
stream:bloc.checkText,
builder:(BuildContext context, AsyncSnapshot<String> snapshot){
return RaisedButton(
.....
onPressed: !snapshot.hasdata ? null : buttonOnPressedEvent(), // handle event when the textfield is valid or not
color: !snapshot.hasdata ? Colors.grey : Colors.blue // this used to change preview color button if the data has exist
.....
);
});
Hope that this can give you some inspiration how to solve your problem, good luck!

Flutter TextField, how to use different style for label inside vs above the text field

I have the following TextField:
TextField(
decoration: InputDecoration(
labelStyle: TextStyle(
color: I_WANT_TO_CHANGE_THIS,
),
labelText: widget.label,
),
);
How do I change the color so that when it's inside the text field (a hint), it's GRAY, and when it's floating above the text field (being focused), it's BLACK.
Try using a FocusNode:
class _MyHomePageState extends State<MyHomePage> {
FocusNode _focusNode = FocusNode();
Color color;
#override
Widget build(BuildContext context) {
_focusNode.addListener(() {
setState(() {
color = _focusNode.hasFocus ? Colors.blue : Colors.red;
});
});
return Scaffold(
body: Center(
child: TextField(
focusNode: _focusNode,
decoration: InputDecoration(
labelText: 'Label',
labelStyle: TextStyle(
color: _focusNode.hasFocus ? Colors.blue : Colors.red,
)
),
autofocus: false,
),
)
);
}
}
Notice that in this particular example the textfield will always be in focus once selected, since there's only one textfield.

How to create number input field in Flutter?

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.
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
),
],
)),
);
}
}
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)
)
)
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
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
...
https://docs.flutter.io/flutter/material/TextFormField/TextFormField.html
https://docs.flutter.io/flutter/services/TextInputType-class.html
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.
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.
double.parse() converts from string to double.
Don't forget you need:
import 'package:flutter/services.dart';
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.
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]')),
],
),
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;
},
),
You can try this:
TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
prefixIcon: Text("Enter your number: ")
),
initialValue: "5",
onSaved: (input) => _value = num.tryParse(input),
),
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,
);
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)
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;
}
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;
},
),
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();
},
);
}
}
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]')),
])
You need to add the line
keyboardType: TextInputType.phone,
Within the block "TextFormField". Example below:
TextField(
controller: _controller,
keyboardType: TextInputType.phone,
),
It should look like this: