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

Flutter Web应用开启显示密码功能后无法展示已输入密码

Flutter Web 密码显示切换功能异常问题

我在Flutter Web应用里实现密码显示/隐藏的切换功能,初始将isObscure设为false时能正常显示明文,点击切换按钮可以隐藏密码,但无法再次切换回显示状态。打印变量值确认isObscure和isPasswordObscure能在true和false间正常切换,且已调用setState,但问题仍未解决。尝试过多个线上示例,在Web端均无效,想询问这是否是Web端特有的问题,或是我遗漏了配置?

相关代码

@override
Widget build(BuildContext context) {
  c_width = MediaQuery.of(context).size.width*0.8;
  return Scaffold(
    appBar: AppBar(title: Text("App"),),
    body: signUpWidget(widget.signUpValue),
  );
}

Widget signUpWidget(String? rl)  {
  switch(rl) {
    case 'User': {
      return SingleChildScrollView(
        child: Container (
          width: c_width,
          padding: const EdgeInsets.all(16.0),
          child: Column(
            child: Column(
              children: <Widget>[
                TextFormField(
                  obscureText: isObscure,
                  decoration: InputDecoration(
                    suffix: TextButton(
                      child: isPasswordObscure
                        ? Text(
                            'Show',
                            style: TextStyle(color: Colors.grey),
                          )
                        : Text(
                            'Hide',
                            style: TextStyle(color: Colors.grey),
                          ),
                      onPressed: () {
                        setState(() { 
                          isObscure = !isObscure; 
                          isPasswordObscure = !isObscure;
                        });
                      },
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      );
    }
    // 其他case省略
  }
}

问题原因及解决办法

这是Flutter Web端TextFormField切换obscureText状态时的常见渲染问题,核心是Web端输入框组件的DOM没有同步状态变更。可以通过以下方式解决:

  1. 给TextFormField添加唯一Key
    强制Flutter重新构建输入框组件,确保状态变更同步到Web DOM:

    TextFormField(
      key: ValueKey(isObscure), // 添加该Key
      obscureText: isObscure,
      // 其余配置不变
    )
    
  2. 替换suffix为suffixIcon
    Web端对suffixIcon的状态更新支持更稳定,替换后能避免渲染异常:

    decoration: InputDecoration(
      suffixIcon: TextButton(
        child: isPasswordObscure
          ? Text('Show', style: TextStyle(color: Colors.grey))
          : Text('Hide', style: TextStyle(color: Colors.grey)),
        onPressed: () {
          setState(() { 
            isObscure = !isObscure; 
            isPasswordObscure = !isPasswordObscure; // 直接取反自身,逻辑更清晰
          });
        },
      ),
    )
    
  3. 简化状态变量
    无需两个状态变量,只用一个isObscure即可完成逻辑,减少出错概率:

    // 仅保留isObscure变量,初始值设为false
    TextFormField(
      obscureText: isObscure,
      decoration: InputDecoration(
        suffixIcon: TextButton(
          child: isObscure ? Text('Show') : Text('Hide'),
          onPressed: () => setState(() => isObscure = !isObscure),
        ),
      ),
    )
    

另外需确认signUpWidget是否在State类的build方法内调用,确保setState能触发该组件重建。如果signUpWidget是独立无状态组件,需改为有状态组件,或通过参数传递状态变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:21:09