Flutter中如何完全隐藏TextFormField的输入字符?
解决Flutter密码输入短暂显示字符的问题
可以通过自定义TextEditingController实现完全隐藏输入字符、仅显示遮挡符号的效果,无需依赖特殊字体。
方法1:自定义ObscuredTextEditingController
创建继承自TextEditingController的子类,内部保存真实密码,对外始终返回与输入长度匹配的遮挡字符,彻底避免输入字符短暂显示的问题。
示例代码:
class ObscuredTextEditingController extends TextEditingController { final String obscureChar; String _realPassword = ''; ObscuredTextEditingController({this.obscureChar = '●'}); @override String get text => obscureChar * _realPassword.length; @override set text(String newText) { _realPassword = newText; value = value.copyWith( text: text, selection: TextSelection.collapsed(offset: text.length), composing: TextRange.empty, ); } @override void updateEditingValue(TextEditingValue newValue) { _realPassword = newValue.text; final obscuredText = obscureChar * _realPassword.length; super.updateEditingValue(TextEditingValue( text: obscuredText, selection: TextSelection.collapsed(offset: obscuredText.length), composing: TextRange.empty, )); } // 获取真实密码的方法 String get realPassword => _realPassword; }
使用方式:
final passwordController = ObscuredTextEditingController(); TextFormField( controller: passwordController, // 无需再设置obscureText: true decoration: const InputDecoration(labelText: '密码'), validator: (_) { if (passwordController.realPassword.isEmpty) { return '请输入密码'; } return null; }, )
方法2:状态管理配合TextField(简化版)
如果不想自定义控制器,也可以通过维护真实密码状态,手动控制显示内容:
String _realPassword = ''; String _displayText = ''; TextField( onChanged: (input) { if (input.length > _realPassword.length) { // 新增字符时更新真实密码 _realPassword += input.substring(_realPassword.length); } else if (input.length < _realPassword.length) { // 删除字符时截断真实密码 _realPassword = _realPassword.substring(0, input.length); } setState(() => _displayText = '●' * _realPassword.length); }, controller: TextEditingController(text: _displayText), decoration: const InputDecoration(labelText: '密码'), )
注意事项
- 使用自定义控制器时,获取输入内容需调用
controller.realPassword,不能直接用text属性(返回的是遮挡字符)。 - 遮挡字符可按需替换为
*或其他符号。
内容的提问来源于stack exchange,提问作者matteoh
相关产品推荐
相关产品推荐

