![](/img/trans.png)
[英]Flutter: How to add a TextField or TextFormField programmatically
[英]How to add a mask in a TextField in Flutter?
我正在嘗試將日期掩碼添加到文本字段,因為我不喜歡日期選擇器,因為例如出生日期,它不那么靈活。 之后,從字符串轉換為日期時間,我相信我可以繼續這個項目,在此先感謝。
static final TextEditingController _birthDate = new TextEditingController();
new TextFormField(
controller: _birthDate,
maxLength: 10,
keyboardType: TextInputType.datetime,
validator: _validateDate
), String _validateDate(String value) {
if(value.isEmpty)
return null;
if(value.length != 10)
return 'Enter date in DD / MM / YYYY format';
return null;
}
我修改了一些東西,並設法得到預期的結果。
我創建了這個類來定義變量
static final _UsNumberTextInputFormatter _birthDate = new _UsNumberTextInputFormatter();
class _UsNumberTextInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue ) {
final int newTextLength = newValue.text.length;
int selectionIndex = newValue.selection.end;
int usedSubstringIndex = 0;
final StringBuffer newText = new StringBuffer();
if (newTextLength >= 3) {
newText.write(newValue.text.substring(0, usedSubstringIndex = 2) + '/');
if (newValue.selection.end >= 2)
selectionIndex ++;
}
if (newTextLength >= 5) {
newText.write(newValue.text.substring(2, usedSubstringIndex = 4) + '/');
if (newValue.selection.end >= 4)
selectionIndex++;
}
if (newTextLength >= 9) {
newText.write(newValue.text.substring(4, usedSubstringIndex = 8));
if (newValue.selection.end >= 8)
selectionIndex++;
}
// Dump the rest.
if (newTextLength >= usedSubstringIndex)
newText.write(newValue.text.substring(usedSubstringIndex));
return new TextEditingValue(
text: newText.toString(),
selection: new TextSelection.collapsed(offset: selectionIndex),
);
}
}
最后我在文本字段中添加了一個inputformat
new TextFormField(
maxLength: 10,
keyboardType: TextInputType.datetime,
validator: _validateDate,
decoration: const InputDecoration(
hintText: 'Digite sua data de nascimento',
labelText: 'Data de Nascimento',
),
inputFormatters: <TextInputFormatter> [
WhitelistingTextInputFormatter.digitsOnly,
// Fit the validating format.
_birthDate,
]
),
現在沒事了,謝謝
https://pub.dartlang.org/packages/masked_text
masked_text
一個掩蓋文本的包,所以如果你想要一個電話面具,或郵政編碼或任何類型的面具,只需使用它:D
入門
它非常簡單,就像其他所有的Widget一樣。
new MaskedTextField
(
maskedTextFieldController: _textCPFController,
mask: "xx/xx/xxxx",
maxLength: 10,
keyboardType: TextInputType.number,
inputDecoration: new InputDecoration(
hintText: "Digite a data do seu nascimento", labelText: "Data"),
);
'x'是您的文本將具有的普通字符。
這個樣本最終再現了這樣的東西: 11/02/1995
。
我的解決方案:
class MaskTextInputFormatter extends TextInputFormatter {
final int maskLength;
final Map<String, List<int>> separatorBoundries;
MaskTextInputFormatter({
String mask = "xx.xx.xx-xxx.xx",
List<String> separators = const [".", "-"],
}) : this.separatorBoundries = {
for (var v in separators)
v: mask.split("").asMap().entries.where((entry) => entry.value == v).map((e) => e.key).toList()
},
this.maskLength = mask.length;
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
final int newTextLength = newValue.text.length;
final int oldTextLength = oldValue.text.length;
// removed char
if (newTextLength < oldTextLength) return newValue;
// maximum amount of chars
if (oldTextLength == maskLength) return oldValue;
// masking
final StringBuffer newText = StringBuffer();
int selectionIndex = newValue.selection.end;
// extra boundaries check
final separatorEntry1 = separatorBoundries.entries.firstWhereOrNull((entry) => entry.value.contains(oldTextLength));
if (separatorEntry1 != null) {
newText.write(oldValue.text + separatorEntry1.key);
selectionIndex++;
} else {
newText.write(oldValue.text);
}
// write the char
newText.write(newValue.text[newValue.text.length - 1]);
return TextEditingValue(
text: newText.toString(),
selection: TextSelection.collapsed(offset: selectionIndex),
);
}
}
此解決方案檢查日期是否超出范圍(例如,沒有像13這樣的月份)。 這是非常低效的,但它的工作原理。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class DateFormatter extends TextInputFormatter {
final String mask = 'xx-xx-xxxx';
final String separator = '-';
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
if(newValue.text.length > 0) {
if(newValue.text.length > oldValue.text.length) {
String lastEnteredChar = newValue.text.substring(newValue.text.length-1);
if(!_isNumeric(lastEnteredChar)) return oldValue;
if(newValue.text.length > mask.length) return oldValue;
if(newValue.text.length < mask.length && mask[newValue.text.length - 1] == separator) {
String value = _validateValue(oldValue.text);
print(value);
return TextEditingValue(
text: '$value$separator$lastEnteredChar',
selection: TextSelection.collapsed(
offset: newValue.selection.end + 1,
),
);
}
if(newValue.text.length == mask.length) {
return TextEditingValue(
text: '${_validateValue(newValue.text)}',
selection: TextSelection.collapsed(
offset: newValue.selection.end,
),
);
}
}
}
return newValue;
}
bool _isNumeric(String s) {
if(s == null) return false;
return double.parse(s, (e) => null) != null;
}
String _validateValue(String s) {
String result = s;
if (s.length < 4) { // days
int num = int.parse(s.substring(s.length-2));
String raw = s.substring(0, s.length-2);
if (num == 0) {
result = raw + '01';
} else if (num > 31) {
result = raw + '31';
} else {
result = s;
}
} else if (s.length < 7) { // month
int num = int.parse(s.substring(s.length-2));
String raw = s.substring(0, s.length-2);
if (num == 0) {
result = raw + '01';
} else if (num > 12) {
result = raw + '12';
} else {
result = s;
}
} else { // year
int num = int.parse(s.substring(s.length-4));
String raw = s.substring(0, s.length-4);
if (num < 1950) {
result = raw + '1950';
} else if (num > 2006) {
result = raw + '2006';
} else {
result = s;
}
}
print(result);
return result;
}
}
您現在可以使用 TextField 的布爾屬性“obscureText”來屏蔽輸入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.