在5个字符后自动添加破折号



我想在输入至少5个字符后用短划线格式化pin条目。因此,每个用户输入10位数的pin码,每5个字符后会自动添加一个破折号。

TextField(
maxLength: 10,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.characters,
onChanged: (text) {
pin = text;
},
textAlign: TextAlign.left,
// keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
errorText: _errorText,
icon: Icon(
Icons.dialpad,
),
labelText: '8-digit PIN',
contentPadding: EdgeInsets.symmetric(vertical: 10.0),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent, width: 2),
),
focusedErrorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2),
),
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFFF696969), width: 1),
),
),
),

您应该在TextField中添加一个控制器,以便控制文本字段的值。

TextField(
...
controller: _controller,
...
)

将您的onChange事件函数更改为以下内容:

onChanged: (String text) {
final sanitizedText = text.replaceAll('-', '');
_controller.text = _addDashes(sanitizedText);
_controller.selection = TextSelection.collapsed(offset: _controller.text.length); 
},

这将在TextField中获取当前文本,删除短划线,并将其存储在一个变量中。然后,该函数使用控制器将TextField的文本替换为应用了_addDashes函数的净化文本的值。此外,它会将光标移动到文本字段的末尾,因为当我们更改值时,光标会跳到开头。

String _addDashes(String text) {
const int addDashEvery = 5;
String out = '';

for (int i = 0; i < text.length; i++) {
if (i + 1 > addDashEvery && i % addDashEvery == 0) {
out += '-';
}

out += text[i];
}

return out;
}

您可以尝试这种方法,当文本达到特定长度时,使用TextEditingController进行控制,并使用_controller.selection继续添加破折号的位置,如果不处理此选择属性,则选择将重新启动到开头:

class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _controller = TextEditingController();
late FocusNode myFocusNode;
@override
void initState() {
myFocusNode = FocusNode();
_controller.addListener(() {
if(_controller.text.length == 4) {
_controller.text = _controller.text + '-';
_controller.selection = TextSelection.fromPosition(TextPosition(offset: _controller.text.length));;
}
});
super.initState();
}
@override
void didChangeDependencies() {
print(_controller.text);
super.didChangeDependencies();
}
@override
void dispose() {
_controller.dispose();
myFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.lightBlue,
body: Container(
child: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
maxLength: 10,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.characters,
controller: _controller,
focusNode: myFocusNode,
onChanged: (text) {},
textAlign: TextAlign.left,
decoration: const InputDecoration(
icon: Icon(
Icons.dialpad,
),
labelText: '8-digit PIN',
contentPadding: EdgeInsets.symmetric(vertical: 10.0),
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent, width: 2),
),
focusedErrorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2),
),
errorBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: Color(0xFFF696969), width: 1),
),
),
),
],
),
),
),
),
);
}
}

最新更新