使用Provider调用函数后TextField文本被清空,如何解决?
问题原因
你的代码中TextEditingController _controller = TextEditingController();是在build方法内部声明的。每次调用provider.changeErrorText()触发notifyListeners()时,Consumer会重建,进而触发build方法重新执行,新的TextEditingController实例会被创建,导致TextField丢失之前的输入内容。
解决方案
将TextEditingController的初始化移到build方法外部,确保它只被创建一次。推荐使用StatefulWidget来管理控制器的生命周期,这也是Flutter的最佳实践。
修改后的代码
TextFieldPage(改为StatefulWidget)
class TextFieldPage extends StatefulWidget { const TextFieldPage({super.key}); @override State<TextFieldPage> createState() => _TextFieldPageState(); } class _TextFieldPageState extends State<TextFieldPage> { // 将控制器声明为State类的成员变量,仅初始化一次 final TextEditingController _controller = TextEditingController(); @override void dispose() { // 页面销毁时销毁控制器,避免内存泄漏 _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final provider = Provider.of<TextFieldProvider__>(context); return Scaffold( body: Column(children: [ Consumer<TextFieldProvider__>( builder: (context, value, child) { return TextField( controller: _controller, decoration: InputDecoration(errorText: value.errorText), ); }, ), ElevatedButton( onPressed: () { if (_controller.text.isEmpty) { provider.changeErrorText('error'); } else { provider.changeErrorText(''); } }, child: const Text("press"), ) ]), ); } }
TextFieldProvider__(无需修改)
class TextFieldProvider__ extends ChangeNotifier { String _errorText = ''; String get errorText => _errorText; void changeErrorText(String text) { _errorText = text; notifyListeners(); } }
额外说明
如果不想改为StatefulWidget,也可以将控制器声明为StatelessWidget的类成员变量:
class TextFieldPage extends StatelessWidget { const TextFieldPage({super.key}); // 声明为类成员变量,确保仅初始化一次 final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { // 其余代码不变 } }
但这种方式的局限性在于:如果TextFieldPage被父组件重新实例化,控制器会被重建,仍可能丢失输入内容。因此更推荐使用StatefulWidget的方案。
内容的提问来源于stack exchange,提问作者Saad
相关产品推荐
相关产品推荐

