Flutter中TextEditingController返回键按下后内容回退问题求助
问题原因与解决方案
问题根源
你遇到的问题核心在于每次页面重建时,FutureBuilder的builder方法都会重新执行,而你在builder里每次都把usernameController的文本重置为接口返回的初始值。
具体来说,你用ConstrainedBox设置了maxHeight: MediaQuery.of(context).size.height,当键盘弹出时,屏幕可用高度会变化,触发页面重建。这时候FutureBuilder的builder会再次被调用,你又执行了usernameController.text = profileResponse.profile.username,直接覆盖了用户输入的内容——按下返回键收起键盘时,屏幕高度再次变化触发重建,文本就会回到初始值。
解决方案
方案一:仅初始化时给Controller赋值
把给controller赋值的逻辑从FutureBuilder的builder里移出来,只在接口请求完成后执行一次,避免每次重建都重置内容。
修改代码如下:
@override void initState() { super.initState(); // 在请求完成后一次性给controller赋值 fetch().then((profileResponse) { if (profileResponse.code == 200) { setState(() { usernameController.text = profileResponse.profile.username; }); } }); } // 修改buildPage方法,移除builder里的赋值逻辑 FutureBuilder<ProfileResponse> buildPage() { return FutureBuilder<ProfileResponse>( future: futureProfileResponse, builder: (context, snapshot) { if (snapshot.hasData) { ProfileResponse profileResponse = snapshot.data!; if (profileResponse.code == 200) { return Padding( padding: const EdgeInsets.all(24), child: Column( children: [ TextField( controller: usernameController, decoration: const InputDecoration( labelText: 'Username', ), ), ], ), ); } } return const Center(child: CircularProgressIndicator()); }); }
方案二:优化布局减少不必要重建
如果需要保留ConstrainedBox处理键盘弹出时的滚动需求,可以调整布局逻辑,避免因屏幕高度变化频繁触发重建:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Edit profile'), ), // 用viewInsets处理键盘弹出的底部间距,同时把maxHeight改为minHeight body: SingleChildScrollView( padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), child: ConstrainedBox( constraints: BoxConstraints( minHeight: MediaQuery.of(context).size.height), child: buildPage()))); }
这样既保证页面至少占满屏幕,又能让TextField在键盘弹出时自动上移,同时减少因高度变化触发的重建次数。
内容的提问来源于stack exchange,提问作者guti
相关产品推荐
相关产品推荐

