我
m building a form with several fields and I
正在使用控制器初始化它们的值。
有些字段是纯文本字段,但其他字段有掩码,例如电话和邮政编码字段。
一旦我将字段置于焦点上并开始退格以擦除最后一个字符,它就可以在没有遮罩的字段上正常工作。带掩码的字段会清除该字段的全部内容。
我正在使用 Flutter 3 和 mask_text_input_formatter ^2.4.0。
这是我用两个字段重现问题的代码。 如果运行此代码并将焦点放在名称字段上,您可以退格它,并且只有最后一个字符会被清除。 但在电话字段中,这会导致整个字段被清除。
import 'package:flutter/material.dart';
import 'package:mask_text_input_formatter/mask_text_input_formatter.dart';
final phoneMaskFormatter = MaskTextInputFormatter(mask: '(###) ### ####');
class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);
@override
State<Test> createState() => _TestState();
}
class _TestState extends State<Test> {
final _formKey = GlobalKey<FormState>();
late TextEditingController _nameController;
late TextEditingController _phoneController;
var myData = {'name': 'William', 'phone': '(305) 786 1234'};
@override
void initState() {
super.initState();
_nameController = TextEditingController();
_phoneController = TextEditingController();
_nameController.text = myData['name']!;
_phoneController.text = myData['phone']!;
}
@override
void dispose() {
super.dispose();
_nameController.dispose();
_phoneController.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Form(
key: _formKey,
child: Container(
padding: EdgeInsets.all(50),
child: Column(
children: [
Text('Name: ${myData['name']}'),
Text('Phone: ${myData['phone']}'),
SizedBox(height: 100),
TextFormField(
controller: _nameController,
onChanged: (value) {
// do my stuff
setState(() {
myData['name'] = value;
});
}),
TextFormField(
controller: _phoneController,
inputFormatters: [phoneMaskFormatter],
onChanged: (value) {
// do my stuff
setState(() {
myData['phone'] = value;
});
}),
],
),
),
),
),
);
}
}
现在唯一对我有用的就是摘掉电话区域的面具。
使用 extended_masked_text: ^2.3.1 满足您的要求。
_phoneController 的声明和初始化与您所做的相同。
MaskedTextController _phoneController =
MaskedTextController(mask: '(000) 000 0000');
void initState() {
...
_phoneController.text = myData['phone']!;
...
}
并删除
inputFormatters: [numberController]
。
我找到了一个可能适合您的解决方案,因为我也遇到过同样的情况。只需将 MaskTextInputFormatter 替换为下一个 PhoneInputFormatter 即可。
class PhoneInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
// Only process when the user is entering text
if (newValue.text.isNotEmpty) {
// Remove all non-digit characters
String newText = newValue.text.replaceAll(RegExp(r'\D'), '');
// If the new text length is greater than 10 (including the area code), truncate it
if (newText.length > 10) {
newText = newText.substring(0, 10);
}
// Format the text according to the mask
String formattedText = '';
for (int i = 0; i < newText.length; i++) {
if (i == 0) {
formattedText += '(';
} else if (i == 3) {
formattedText += ') ';
} else if (i == 6) {
formattedText += '-';
}
formattedText += newText[i];
}
// Return the formatted text
return newValue.copyWith(
text: formattedText,
selection: TextSelection.collapsed(offset: formattedText.length),
);
}
// Return the unchanged value
return newValue;
}
}