Flutter如何实现右侧带固定不可删除单位的数字TextField输入框
需求说明
实现身高输入文本框,要求:
- 输入数值后展示效果为
[数值] cm,例:180 cm - 单位
cm始终固定展示,不允许用户删除 - 之前尝试使用flutter_masked_text2库,通过配置
MaskedTextController(mask: '000 cm')实现未达预期
原有方案失效原因
flutter_masked_text2的掩码规则中,普通字母会被识别为可输入占位符(默认规则下0匹配数字、a匹配字母),配置的000 cm里的c、m会被判定为需要用户输入对应字母的位置,不会作为固定文本展示,且写死3位数字的掩码规则灵活性差,无法适配不同长度的数值输入。
可行实现方案
方案1:单位紧跟输入内容(和示例效果完全一致)
自定义TextEditingController,自动拼接固定单位、锁定光标位置、过滤非法输入,无需依赖第三方库。
- 编写自定义控制器:
class FixedUnitTextController extends TextEditingController { final String unit; FixedUnitTextController({required this.unit, String? initText}) : super(text: initText); @override set text(String newText) { // 剥离已拼接的单位,避免重复叠加 String pureInput = newText.endsWith(' $unit') ? newText.substring(0, newText.length - unit.length - 1) : newText; // 身高场景仅保留数字,可根据自身需求调整过滤规则 pureInput = pureInput.replaceAll(RegExp(r'[^0-9]'), ''); // 拼接最终显示文本 final displayText = pureInput.isEmpty ? '' : '$pureInput $unit'; super.text = displayText; // 强制光标停在数字末尾、单位之前,避免用户跑到单位位置删除内容 selection = TextSelection.collapsed( offset: displayText.isEmpty ? 0 : displayText.length - unit.length - 1 ); } }
- 页面中使用:
// 初始化控制器 final heightController = FixedUnitTextController(unit: 'cm'); // 传给TextField TextField( controller: heightController, keyboardType: TextInputType.number, // 其余输入框样式配置按需添加 )
- 取值方式:使用前手动剥离单位即可拿到纯数值
double? getInputHeight() { final pureValue = heightController.text.replaceAll(' cm', ''); return double.tryParse(pureValue); }
*如果需要支持小数输入(如以米为单位输入1.75 m),只需修改控制器内的正则过滤规则,将
.加入允许保留的字符集即可。
方案2:单位固定在输入框最右侧(实现成本最低)
如果不需要单位紧跟输入文本,仅需要单位固定在输入框右侧区域,直接用输入框自带的装饰属性即可,无需自定义控制器:
TextField( keyboardType: TextInputType.number, decoration: InputDecoration( suffixText: 'cm', // 可自定义单位样式和输入文本保持一致 suffixStyle: TextStyle( fontSize: 16, color: Colors.black87 ) ), )
内容的提问来源于stack exchange,提问作者kokoko
相关产品推荐
相关产品推荐

