Flutter 如何清除颤振中TextFormField中的错误消息
在我的代码中,我验证电话号码。如果电话号码不正确-我会显示错误消息。但是,当用户开始编辑号码时,我想隐藏此错误消息 我用Flutter 如何清除颤振中TextFormField中的错误消息,flutter,Flutter,在我的代码中,我验证电话号码。如果电话号码不正确-我会显示错误消息。但是,当用户开始编辑号码时,我想隐藏此错误消息 我用currentState.reset()找到了解决方案,但它似乎不是一个好的解决方案。我必须处理保存文本和光标位置的问题。我还有一件小艺术品。通常,当我按住backspace键时,它会逐个删除符号。如果在显示错误消息时执行此操作,则错误消息将消失,并且仅删除一个符号 有人知道这个案子的正确解决方案吗 final TextEditingController controller
currentState.reset()
找到了解决方案,但它似乎不是一个好的解决方案。我必须处理保存文本和光标位置的问题。我还有一件小艺术品。通常,当我按住backspace键时,它会逐个删除符号。如果在显示错误消息时执行此操作,则错误消息将消失,并且仅删除一个符号
有人知道这个案子的正确解决方案吗
final TextEditingController controller = TextEditingController();
final RegExp _phoneRegex = RegExp(r"^\+{1}\d{10, 15}\$");
bool isError = false;
TextSelection currentPosition;
return Column(
children: <Widget>[
Form(
key: _textKey,
child: TextFormField(
controller: controller,
validator: (str) {
isError = true;
if (str.isEmpty) {
return err_empty_field;
} else if (!_phoneRegex.hasMatch(str)) {
return err_invalid_phone;
}
isError = false;
},
),
onChanged: () {
if (controller.selection.start < 0 &&
controller.text.length > 0) {
TextSelection position =
controller.text.length > currentPosition.start
? currentPosition
: TextSelection.fromPosition(
TextPosition(offset: controller.text.length));
controller.selection = position;
}
if (isError) {
isError = false;
currentPosition = controller.selection;
if (currentPosition.start > controller.text.length) {
currentPosition = TextSelection.fromPosition(
TextPosition(offset: controller.text.length));
}
String currentText = controller.text;
_textKey.currentState.reset();
controller.text = currentText;
controller.selection = currentPosition;
}
},
),
RaisedButton(
onPressed: () {
_textKey.currentState.validate();
},
child: Text(login),
)
],
);
final TextEditingController=TextEditingController();
final RegExp_phoneRegex=RegExp(r“^\+{1}\d{10,15}\$”;
bool-isError=false;
文本选择当前位置;
返回列(
儿童:[
形式(
键:_textKey,
子项:TextFormField(
控制器:控制器,
验证人:(str){
isError=真;
如果(str.isEmpty){
返回err\u空字段;
}如果(!\u phoneRegex.hasMatch(str)){
返回错误\无效\电话;
}
isError=错误;
},
),
一旦更改:(){
如果(controller.selection.start)小于0&&
controller.text.length>0){
文本选择位置=
controller.text.length>currentPosition.start
?当前位置
:TextSelection.fromPosition(
TextPosition(偏移量:controller.text.length));
控制器。选择=位置;
}
如果(isError){
isError=错误;
currentPosition=控制器。选择;
if(currentPosition.start>controller.text.length){
currentPosition=TextSelection.fromPosition(
TextPosition(偏移量:controller.text.length));
}
字符串currentText=controller.text;
_textKey.currentState.reset();
controller.text=当前文本;
控制器。选择=当前位置;
}
},
),
升起的按钮(
已按下:(){
_textKey.currentState.validate();
},
子:文本(登录),
)
],
);
这是一个示例,我认为没有必要执行onchange(),函数validate name可以完成这项工作
String validateName(String value) {
String patttern = r'(^[a-zA-Z ]*$)';
RegExp regExp = new RegExp(patttern);
if (value.length == 0) {
return "Name is Required";
} else if (!regExp.hasMatch(value)) {
return "Name must be a-z and A-Z";
}
return null;
}
TextFormField(
controller: _lastname, validator: validateName ,
//initialValue: widget.contact.last_name,
decoration:
InputDecoration(labelText: 'Last name'),
),
void Save() {
if (_keyForm.currentState.validate()) {
// No any error in validation
_keyForm.currentState.save();
................
}
我已经实现了以下两项功能: 1) 编辑时隐藏错误消息 2) 按下登录按钮时验证输入字段 注意:我已经对电话号码regex进行了注释,并对其进行了验证 用于测试的字符串长度<10位
导入“包装:颤振/材料.省道”;
进口“包装:颤振/基础.dart”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:MyHomePage(),
);
}
}
类MyHomePage扩展StatefulWidget{
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
@凌驾
void initState(){
super.initState();
}
最终文本编辑控制器控制器=文本编辑控制器();
//final RegExp_phoneRegex=RegExp(r“^\+{1}\d{10,15}\$”;
bool-isError=false;
bool isWriting=false;
bool isLoginPressed=false;
int计数器=0;
字符串myErrorString=“”;
文本选择当前位置;
final _textKey=GlobalKey();
@凌驾
小部件构建(BuildContext ctx){
返回脚手架(
appBar:appBar(
标题:文本(“MapSample”),
),
主体:容器(
子:列(
儿童:[
形式(
键:_textKey,
子项:TextFormField(
控制器:控制器,
验证人:(str){
myErrorString=“”;
如果(isLoginPressed){
isError=真;
如果(str.isEmpty){
myErrorString='err_empty_field';
返回myErrorString;
}
否则如果(str.length<10){
myErrorString='err_invalid_phone';
validateMe();
返回myErrorString;
}
/*如果(!\u phoneRegex.hasMatch(str)){
myErrorString='err_invalid_phone';
validateMe();
返回myErrorString;
}*/
isError=错误;
myErrorString=“”;
}否则{
myErrorString=“”;
}
},
),
一旦更改:(){
计数器++;
如果(计数器==9){
计数器=0;
isLoginPressed=false;
}
如果(isLoginPressed){
}否则{
isWriting=true;
isLoginPressed=false;
myErrorString=“”;
_textKey.currentState.validate();
}
},
),
升起的按钮(
已按下:(){
计数器=1;
isWriting=false;
isLoginPressed=true;
_textKey.currentState.validate();
},
子项:文本('login'),
)
],
),
),
);
}
void validateMe(){
如果(isLoginPressed){
currentPosition=TextSelection.fromPosition(
TextPosition(偏移量:controller.text.length));
字符串currentText=controller.text;
_textKey.currentState.reset();
controller.text=cur
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState(){
super.initState();
}
final TextEditingController controller = TextEditingController();
// final RegExp _phoneRegex = RegExp(r"^\+{1}\d{10, 15}\$");
bool isError = false;
bool isWriting = false;
bool isLoginPressed = false;
int counter = 0;
String myErrorString = "";
TextSelection currentPosition;
final _textKey = GlobalKey<FormState>();
@override
Widget build(BuildContext ctx) {
return Scaffold(
appBar: AppBar(
title: Text('MapSample'),
),
body: Container(
child: Column(
children: <Widget>[
Form(
key: _textKey,
child: TextFormField(
controller: controller,
validator: (str) {
myErrorString = "";
if(isLoginPressed){
isError = true;
if (str.isEmpty) {
myErrorString = 'err_empty_field';
return myErrorString;
}
else if (str.length < 10) {
myErrorString = 'err_invalid_phone';
validateMe();
return myErrorString;
}
/*else if (!_phoneRegex.hasMatch(str)) {
myErrorString = 'err_invalid_phone';
validateMe();
return myErrorString;
}*/
isError = false;
myErrorString = "";
}else{
myErrorString = "";
}
},
),
onChanged: () {
counter++;
if(counter == 9){
counter = 0;
isLoginPressed = false;
}
if(isLoginPressed){
}else{
isWriting = true;
isLoginPressed = false;
myErrorString = "";
_textKey.currentState.validate();
}
},
),
RaisedButton(
onPressed: () {
counter = 1;
isWriting = false;
isLoginPressed = true;
_textKey.currentState.validate();
},
child: Text('login'),
)
],
),
),
);
}
void validateMe() {
if(isLoginPressed){
currentPosition = TextSelection.fromPosition(
TextPosition(offset: controller.text.length));
String currentText = controller.text;
_textKey.currentState.reset();
controller.text = currentText;
controller.selection = currentPosition;
isWriting = false;
isLoginPressed = true;
}
}
}
final _textKey = GlobalKey<FormState>();
final TextEditingController _controller = TextEditingController();
Widget _getPhoneInputForm() {
final RegExp _phoneRegex = RegExp(r"^\+{1}\d{10,17}");
bool isError = false;
bool isButtonPressed = false;
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 36.0),
child: Form(
key: _textKey,
child: TextFormField(
keyboardType: TextInputType.phone,
decoration: InputDecoration(
hintText: hint_enter_phone,
contentPadding: EdgeInsets.all(24.0),
fillColor: Colors.blueGrey.withOpacity(0.3),
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16.0)),
borderSide: BorderSide(color: Colors.blueGrey))),
controller: _controller,
validator: (str) {
if (!isButtonPressed) {
return null;
}
isError = true;
if (str.isEmpty) {
return err_empty_field;
} else if (!_phoneRegex.hasMatch(str)) {
return err_invalid_phone;
}
isError = false;
},
onFieldSubmitted: (str) {
if (_textKey.currentState.validate()) _phoneLogin();
},
),
onChanged: () {
isButtonPressed = false;
if (isError) {
_textKey.currentState.validate();
}
},
),
),
RaisedButton(
color: Colors.teal,
textColor: Colors.white,
onPressed: () {
isButtonPressed = true;
if (_textKey.currentState.validate()) _phoneLogin();
},
child: Text(login),
)
],
);
}
import 'package:flutter/material.dart';
class WorkGround extends StatefulWidget {
@override
_WorkGroundState createState() => _WorkGroundState();
}
class _WorkGroundState extends State<WorkGround> {
final _formKey = GlobalKey<FormState>();
final _usernameFocusNode = FocusNode();
final _phoneNumberFocusNode = FocusNode();
/*
* Step 1.
* */
String _userNameErrorText;
bool _userNameError = false;
String _phoneNumberErrorText;
bool _phoneNumberError = false;
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextFormField(
focusNode: _usernameFocusNode,
decoration: InputDecoration(
labelText: 'Username',
/*
* Step 2
* */
errorText: _userNameErrorText, // Handling error manually
),
textInputAction: TextInputAction.next,
/*
* Step 3
* */
validator: (value) {
setState(() {
if(value.isEmpty) {
_userNameError = true;
_userNameErrorText = 'Enter Username';
}
});
return null; // Return null to handle error manually.
},
/*
* Step 4
* */
onChanged: (value) {
setState(() {
_userNameError = false;
_userNameErrorText = null; // Resets the error
});
},
/*
* Step 5
* */
onFieldSubmitted: (value) {
_formKey.currentState.validate(); // Trigger validation
if(!_userNameError) {
FocusScope.of(context).requestFocus(_phoneNumberFocusNode);
}
},
),
TextFormField(
focusNode: _phoneNumberFocusNode,
decoration: InputDecoration(
labelText: 'Phone Number',
/*
* Step 2
* */
errorText: _phoneNumberErrorText, // Handling error manually
),
textInputAction: TextInputAction.done,
/*
* Step 3
* */
validator: (value) {
setState(() {
if(value.isEmpty) {
_phoneNumberError = true;
_phoneNumberErrorText = 'Enter Phone number';
} else if( value.length < 10) {
_phoneNumberError = true;
_phoneNumberErrorText = 'Invalid Phone number';
}
});
return null; // Return null to handle error manually.
},
/*
* Step 4
* */
onChanged: (value) {
setState(() {
_phoneNumberError = false;
_phoneNumberErrorText = null; // Resets the error
});
},
/*
* Step 5
* */
onFieldSubmitted: (value) {
_formKey.currentState.validate(); // Trigger validation
if(!_phoneNumberError) {
// submit form or whatever your code flow is...
}
},
),
],
),
),
);
}
}
bool _autovalidate = false;
Form(
key: _textKey,
autovalidate: _autovalidate,
...
)
RaisedButton(
onPressed: () {
if (_textKey.currentState.validate()) {
print('valid');
} else {
print('invalid');
setState(() => _autoValidate = true);
}
},
child: Text(login),
)
Form(
autovalidateMode: AutovalidateMode.onUserInteraction`.
...
)
...
AutovalidateMode _autoValidate = AutovalidateMode.disabled;
Form(
key: _textKey,
autovalidateMode: _autovalidate,
...
)
RaisedButton(
onPressed: () {
if (_textKey.currentState.validate()) {
print('valid');
} else {
print('invalid');
setState(() => _autoValidate = AutovalidateMode.always);
}
},
child: Text("login"),
)