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

Flutter TextFormField修改内容切换字段后恢复初始值问题

问题原因

TextEditingController的赋值逻辑被放置在build生命周期方法中,Flutter触发任何页面重绘行为(输入框聚焦唤起键盘、状态更新、组件树变更等)时都会重新执行build方法,每次执行都会强制覆盖输入框内容为widget.account的初始值,导致用户修改的内容被重置。

修复方案

把初始赋值逻辑移动到initState生命周期中,仅在页面首次初始化时执行一次即可:

class _AccountScreenState extends State<AccountScreen> {
  final api = ApiServices();
  var formKey = GlobalKey<FormState>();
  var emailController = TextEditingController();
  var pwdController = TextEditingController();
  var phoneController = TextEditingController();

  @override
  void initState() {
    super.initState();
    // 初始赋值仅在页面初始化时执行一次
    emailController.text = widget.account.email!;
    phoneController.text = widget.account.phoneNumber!;
  }

  @override
  Widget build(BuildContext context) {
    // 移除原build方法中的controller赋值代码
    // 剩余原有build逻辑保持不变
    ...
    child: TextFormField(
      controller: emailController,
      decoration: InputDecoration(
        prefixText: "Email: ",
        prefixStyle: TextStyle(fontWeight: FontWeight.w600),
        labelText: "E-mail",
        border: OutlineInputBorder(borderSide: BorderSide.none),
        fillColor: Colors.white,
        filled: true
      ),
    ),
    ...
  }
}

如果存在父组件传递的widget.account会动态更新的场景,可额外添加didUpdateWidget逻辑按需更新输入框内容:

@override
void didUpdateWidget(covariant AccountScreen oldWidget) {
  super.didUpdateWidget(oldWidget);
  // 仅当account参数发生变化时才更新输入框内容
  if (oldWidget.account != widget.account) {
    emailController.text = widget.account.email!;
    phoneController.text = widget.account.phoneNumber!;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:42:04