为什么TextField在周围视图显示/隐藏时会失去焦点?
问题原因
你当前通过条件判断直接替换Column中的子Widget(在Text和SizedBox.shrink()之间切换),当上下两个提示文本同时触发显隐切换时,Column的子Widget树结构会发生显著变化。Flutter的焦点系统依赖Widget树的稳定性来跟踪焦点所属的节点,这种结构变动会导致焦点管理器无法持续识别TextField的身份,最终造成焦点丢失。而仅切换其中一个提示文本时,树结构变化幅度小,焦点系统仍能维持对TextField的焦点追踪,因此不会出现问题。
正确解决方法
不要直接替换Widget,改用Visibility组件控制提示文本的显示/隐藏。Visibility只会控制Widget的可见性和布局占用,不会改变Widget树的结构,能保持树的稳定性,避免焦点丢失。
修改后的代码示例:
class FooPage extends StatefulWidget { const FooPage({Key? key}) : super(key: key); @override State<StatefulWidget> createState() { return FooState(); } } class FooState extends State<FooPage> { TextEditingController controller = TextEditingController(); bool show = true; @override void initState() { super.initState(); controller.addListener(() { setState(() => show = controller.text.length < 5); }); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Visibility( visible: show, child: const Text("hello1"), ), TextField(controller: controller), Visibility( visible: show, child: const Text("hello2"), ), ], ), ); } }
你也可以给TextField添加GlobalKey,帮助Flutter识别相同的Widget实例,不过Visibility是更简洁贴合场景的方案。
内容的提问来源于stack exchange,提问作者PesaThe
相关产品推荐
相关产品推荐

