You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MaskTextInputFormatter的TextFormField退格时清空全部内容问题

解决mask_text_input_formatter退格清空整个字段的问题

问题出在直接给TextEditingController的text属性赋值带掩码的字符串,导致mask_text_input_formatter内部状态未同步,退格时无法正确处理输入逻辑。

解决方案

不要直接赋值带掩码的文本,而是通过掩码格式化器处理原始数字后再设置到控制器,确保格式化器内部状态同步:

  1. 从已有带掩码的电话号码中提取纯数字内容
  2. 通过mask_text_input_formatter的formatEditUpdate方法生成合规的带掩码文本
  3. 将处理后的文本赋值给控制器

修正后的代码

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(text: myData['name']!);
    
    // 提取电话号码中的纯数字
    final rawPhone = myData['phone']!.replaceAll(RegExp(r'[^0-9]'), '');
    // 通过格式化器生成带掩码的合规文本
    final formattedPhone = phoneMaskFormatter.formatEditUpdate(
      const TextEditingValue(),
      TextEditingValue(text: rawPhone),
    ).text;
    _phoneController = TextEditingController(text: formattedPhone);
  }

  @override
  void dispose() {
    _nameController.dispose();
    _phoneController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Form(
          key: _formKey,
          child: Container(
            padding: const EdgeInsets.all(50),
            child: Column(
              children: [
                Text('Name: ${myData['name']}'),
                Text('Phone: ${myData['phone']}'),
                const SizedBox(height: 100),
                TextFormField(
                  controller: _nameController,
                  onChanged: (value) {
                    setState(() {
                      myData['name'] = value;
                    });
                  },
                ),
                TextFormField(
                  controller: _phoneController,
                  inputFormatters: [phoneMaskFormatter],
                  onChanged: (value) {
                    setState(() {
                      myData['phone'] = value;
                    });
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

原理说明

直接赋值带掩码的文本时,mask_text_input_formatter没有记录输入的历史状态,退格操作触发时,它无法正确识别当前光标位置与已输入内容的对应关系,从而错误清空整个字段。通过格式化器处理原始值初始化,能让格式化器同步内部状态,确保后续所有输入操作(包括退格)都按预期工作。

内容的提问来源于stack exchange,提问作者Adriano Marqueze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:05:40