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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:55:00