Flutter中使用PageView切换页面后TextFormField输入内容丢失是什么原因?
问题根因
- PageView默认销毁不可见子页面:Flutter原生PageView没有开启子页面保活能力,当你切换到其他页面后,不在可视区域的旧页面会被系统回收销毁,再次切回时会重新执行build方法重建整个页面结构。
- 输入内容没有绑定回填逻辑:你虽然在
onChanged、onSaved回调中把输入的邮箱值存储到了email变量中,但页面重建时TextFormField不会主动读取email变量的已有值回填到输入框中,新生成的输入框默认是空值。 - 控制器实例随页面销毁重置:你的
_emailCtrl如果是在子页面的State中初始化的,页面销毁时控制器也会同步被销毁,重建页面时生成的新控制器没有存储之前的输入内容,自然显示为空。
解决方法
方案1:开启子页面保活(最简单)
给每个PageView的子页面State混入AutomaticKeepAliveClientMixin,重写wantKeepAlive属性返回true,即可让PageView保留所有子页面的状态不被销毁,示例实现:
class EmailPage extends StatefulWidget { const EmailPage({super.key}); @override State<EmailPage> createState() => _EmailPageState(); } class _EmailPageState extends State<EmailPage> with AutomaticKeepAliveClientMixin { final _emailCtrl = TextEditingController(); String email = ''; // 开启保活 @override bool get wantKeepAlive => true; @override Widget build(BuildContext context) { // 必须调用父类build方法 super.build(context); // 此处返回你原有定义的Form组件代码即可 return Form( // 你的原有Form代码... ); } @override void dispose() { _emailCtrl.dispose(); super.dispose(); } }
方案2:状态跨页面持久化
如果你不需要保活页面,可以把所有表单字段存储到PageView的父组件、或者全局状态管理类中,在子页面初始化时把已存储的值回填到输入框,两种回填方式二选一即可:
- 给TextFormField设置
initialValue属性:
TextFormField( initialValue: email, // 绑定已存储的邮箱值 // 其余原有属性不变 )
- 初始化控制器时传入已有值:
// 父组件/全局状态传入已存储的email值 final _emailCtrl = TextEditingController(text: email);
内容的提问来源于stack exchange,提问作者Hasan Alnatour
相关产品推荐
相关产品推荐

