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

Flutter点击密码可见性图标后表单内容重置问题求助

问题根源

你遇到的问题是因为FutureBuilder在组件状态变化(比如切换obscureText)时会重新执行future回调,导致每次重建都用初始加载的用户信息覆盖输入框内容。本质上是没有把用户修改后的输入值持久化到组件状态中,而是每次依赖FutureBuilder的快照数据。

解决方案

核心思路是:将初始加载的密码值存储到组件的状态变量中,输入框的内容绑定这个状态变量,后续修改和状态切换都基于这个变量操作,避免重复依赖FutureBuilder的异步数据。

具体步骤:

  1. 在页面的State类中定义状态变量,存储当前密码值和密码可见性状态
  2. 单独执行异步加载用户信息的逻辑,在初始化时调用并更新状态变量
  3. 输入框绑定状态变量,修改输入时同步更新状态
  4. 切换密码可见性时,仅更新可见性状态,不触发重新加载初始数据
代码示例
class PasswordFormPage extends StatefulWidget {
  const PasswordFormPage({super.key});

  @override
  State<PasswordFormPage> createState() => _PasswordFormPageState();
}

class _PasswordFormPageState extends State<PasswordFormPage> {
  late String _currentPassword;
  bool _isPasswordObscured = true;
  final TextEditingController _passwordController = TextEditingController();

  @override
  void initState() {
    super.initState();
    // 初始化加载用户信息
    _loadUserInitialInfo();
  }

  @override
  void dispose() {
    _passwordController.dispose();
    super.dispose();
  }

  Future<void> _loadUserInitialInfo() async {
    // 模拟异步获取用户信息
    final userInfo = await _fetchUserInfo();
    setState(() {
      _currentPassword = userInfo.password;
      _passwordController.text = _currentPassword;
    });
  }

  // 模拟接口请求
  Future<UserInfo> _fetchUserInfo() async {
    await Future.delayed(const Duration(milliseconds: 500));
    return UserInfo(password: "Josskkk");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("密码修改")),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: TextField(
          controller: _passwordController,
          obscureText: _isPasswordObscured,
          onChanged: (value) {
            // 同步更新状态变量
            setState(() {
              _currentPassword = value;
            });
          },
          decoration: InputDecoration(
            labelText: "密码",
            suffixIcon: IconButton(
              icon: Icon(
                _isPasswordObscured ? Icons.visibility : Icons.visibility_off,
              ),
              onPressed: () {
                // 仅切换可见性状态,不触发数据重新加载
                setState(() {
                  _isPasswordObscured = !_isPasswordObscured;
                });
              },
            ),
          ),
        ),
      ),
    );
  }
}

// 模拟用户信息模型
class UserInfo {
  final String password;
  UserInfo({required this.password});
}
关键说明
  • 用initState+单独的异步方法加载初始数据,确保只执行一次,避免FutureBuilder重复触发
  • 输入框使用TextEditingController管理内容,并同步到状态变量_currentPassword,保证修改后的值被持久化
  • 切换密码可见性时,仅更新_isPasswordObscured状态,不会触发重新获取用户信息的逻辑,因此输入框内容不会被重置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 07:25:17