我如何在 4 位数字之间留出空格?
需要帮助解决问题
试试下面的代码希望对你有帮助。
您的小部件:
TextFormField(
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
CardNumberFormatter(),
],
textInputAction: TextInputAction.done,
keyboardType: TextInputType.number,
decoration: InputDecoration(
prefixIcon: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.network(
'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/Mastercard-logo.svg/800px-Mastercard-logo.svg.png',
height: 30,
width: 30,
),
),
suffixIcon: const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'Change',
style: TextStyle(color: Colors.green),
),
),
border: const OutlineInputBorder(),
hintText: 'XXXX XXXX XXXX XXXX',
labelText: 'Card Number',
),
maxLength: 19,
onChanged: (value) {},
),
创建用于分隔数字的类:
class CardNumberFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue previousValue,
TextEditingValue nextValue,
) {
var inputText = nextValue.text;
if (nextValue.selection.baseOffset == 0) {
return nextValue;
}
var bufferString = StringBuffer();
for (int i = 0; i < inputText.length; i++) {
bufferString.write(inputText[i]);
var nonZeroIndexValue = i + 1;
if (nonZeroIndexValue % 4 == 0 && nonZeroIndexValue != inputText.length) {
bufferString.write(' ');
}
}
var string = bufferString.toString();
return nextValue.copyWith(
text: string,
selection: TextSelection.collapsed(
offset: string.length,
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(
MyApp(),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(
horizontal: 20,
),
child: TextFormField(
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
CardNumberFormatter(),
],
textInputAction: TextInputAction.done,
keyboardType: TextInputType.number,
decoration: InputDecoration(
prefixIcon: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.network(
'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/Mastercard-logo.svg/800px-Mastercard-logo.svg.png',
height: 30,
width: 30,
),
),
suffixIcon: const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'Change',
style: TextStyle(color: Colors.green),
),
),
border: const OutlineInputBorder(),
hintText: 'XXXX XXXX XXXX XXXX',
labelText: 'Card Number',
),
maxLength: 19,
onChanged: (value) {},
),
);
}
}
class CardNumberFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue previousValue,
TextEditingValue nextValue,
) {
var inputText = nextValue.text;
if (nextValue.selection.baseOffset == 0) {
return nextValue;
}
var bufferString = StringBuffer();
for (int i = 0; i < inputText.length; i++) {
bufferString.write(inputText[i]);
var nonZeroIndexValue = i + 1;
if (nonZeroIndexValue % 4 == 0 && nonZeroIndexValue != inputText.length) {
bufferString.write(' ');
}
}
var string = bufferString.toString();
return nextValue.copyWith(
text: string,
selection: TextSelection.collapsed(
offset: string.length,
),
);
}
}
Darpad
上测试你的代码
所选答案不适合我。但这是我自己的问题版本,它也有一个自定义分隔符希望它能帮助那里的人。
确保您清洁卡号并移除TextField
卡号验证器内的分隔符
validator: (val) {
/// check if it is null empty or whitespace
if (val == null || val.isEmpty || val.trim().isEmpty) {
return "Please input card number";
}
var cleanCardNumber = val.replaceAll(separator, '');
if (_validateCard(cleanCardNumber)) {
return "invalid card number";
}
},
class CardFormatter extends TextInputFormatter {
final String separator;
CardFormatter({required this.separator});
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
var oldS = oldValue.text;
var newS = newValue.text;
var endsWithSeparator = false;
// if you add text
if (newS.length > oldS.length) {
for (var char in separator.characters) {
if (newS.substring(0, newS.length - 1).endsWith(char)) {
endsWithSeparator = true;
}
}
print(
'Ends with separator: $endsWithSeparator, so we will add it with next digit.');
var clean = newS.replaceAll(separator, '');
print('CLEAN add: $clean');
if (!endsWithSeparator && clean.length > 1 && clean.length % 4 == 1) {
return newValue.copyWith(
text: newS.substring(0, newS.length - 1) +
separator +
newS.characters.last,
selection: TextSelection.collapsed(
offset: newValue.selection.end + separator.length,
),
);
}
}
// if you delete text
if (newS.length < oldS.length) {
for (var char in separator.characters) {
if (oldS.substring(0, oldS.length - 1).endsWith(char)) {
endsWithSeparator = true;
}
}
print('Ends with separator: $endsWithSeparator, so we removed it');
var clean = oldS.substring(0, oldS.length - 1).replaceAll(separator, '');
print('CLEAN remove: $clean');
if (endsWithSeparator && clean.isNotEmpty && clean.length % 4 == 0) {
return newValue.copyWith(
text: newS.substring(0, newS.length - separator.length),
selection: TextSelection.collapsed(
offset: newValue.selection.end - separator.length,
),
);
}
}
return newValue;
}
}
keyboardType
keyboardType: TextInputType.number,
inputFormatters
在TextFormField
小部件// somewhere inside the code define the separator
var separator = ' - ';
[...]
// and add this to your `TextFormField` Widget
inputFormatters: [
/// allows card number length of 18 and 4 separators
LengthLimitingTextInputFormatter(18 + separator.length * 4),
CardFormatter(separator: separator),
],
希望这对您有所帮助,也对您有用,请随意将文本输入限制更改为您需要的任何内容。但如果你这样做,也要考虑你想要的分隔符的数量。
在这篇文章中,我找到了一个简单的解决方案,您需要做的就是创建下面的类并将其分配给您的
TextField
小部件:
1-创建这个类:
class CreditCardNumberFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
if(newValue.selection.baseOffset == 0) {
return newValue;
}
String enteredData = newValue.text; // get data enter by used in textField
StringBuffer buffer = StringBuffer();
for (int i = 0;i < enteredData.length;i++) {
// add each character into String buffer
buffer.write(enteredData[i]);
int index = i + 1;
if(index % 4 == 0 && enteredData.length != index) {
// add space after 4th digit
buffer.write(' ');
}
}
return TextEditingValue(
text: buffer.toString(), // final generated credit card number
selection: TextSelection.collapsed(offset: buffer.toString().length) // keep the cursor at end
);
}
}
2- 将新类分配给 TextField 中的 inputFormatters:
TextField(
// ..
inputFormatters: [
LengthLimitingTextInputFormatter(16),
CreditCardNumberFormatter()
],
// ..
),