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

Flutter中FocusNode状态变化时Visibility组件未更新UI的问题求助

Flutter中FocusNode状态变化时Visibility组件未更新UI的问题求助

嘿,我来帮你拆解下问题根源:

你的代码里有两个关键问题,导致FocusNode状态变化时Visibility组件没跟着更新:

1. FocusNode不能在build方法内初始化

你现在在build方法里创建FocusNode focusNode = FocusNode();,这意味着每次Widget重建都会生成全新的FocusNode实例。不仅会丢失之前的焦点状态,焦点变化的回调也无法正确关联到当前Widget的状态。

正确的做法是把FocusNode作为State类的成员变量,在initState中初始化,dispose中释放(避免内存泄漏)。

2. FocusNode状态变化不会自动触发UI重建

FocusNode的hasFocus属性变化时,不会自动调用setState,所以UI不会感知到状态更新。你需要给FocusNode添加监听器,在焦点状态改变时手动触发setState来刷新UI。


下面是修改后的完整代码,我标注了关键修改点:

import 'package:flutter/material.dart';
import 'package:prakty/providers/edituser.dart';
import 'package:provider/provider.dart';

class EditPopUpParent extends StatefulWidget {
  const EditPopUpParent({super.key});

  @override
  State<EditPopUpParent> createState() => _EditPopUpParentState();
}

class _EditPopUpParentState extends State<EditPopUpParent> {
  // 1. 将FocusNode提升为State成员变量
  late FocusNode _focusNode;

  @override
  void initState() {
    super.initState();
    _focusNode = FocusNode();
    // 2. 添加焦点状态监听器,状态变化时触发UI重建
    _focusNode.addListener(() {
      setState(() {});
    });
  }

  @override
  void dispose() {
    // 3. 释放FocusNode,避免内存泄漏
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> editWidgetTypes = [
      Container(),
      editSkillSet(context, _focusNode),
    ];
    return Container(child: editWidgetTypes[1]);
  }

  Widget editSkillSet(context, FocusNode focusNode) {
    var skillBoxes = Provider.of<EditUser>(context).skillBoxes;
    final TextEditingController skillCont =
        TextEditingController(text: skillBoxes[1].keys.single);
    return Column(
      children: [
        Column(mainAxisAlignment: MainAxisAlignment.center, children: [
          Visibility(
            visible: focusNode.hasFocus,
            child: Container(
              width: 100,
              height: 100,
              color: Colors.red,
              child: const Icon(Icons.abc)),
          ),
          TextField(
            controller: skillCont,
            textInputAction: TextInputAction.done,
            focusNode: focusNode,
            decoration:
                const InputDecoration.collapsed(hintText: 'Type Something')),
          ElevatedButton(
            onPressed: () {
              print(focusNode.hasFocus);
            },
            child: const Icon(Icons.check))
        ]),
      ],
    );
  }
}

另外提个小建议:TextEditingController如果关联Provider中的数据,最好在合适时机更新或避免重复创建,不过这不是当前问题的核心,先解决焦点相关的问题就好~

备注:内容来源于stack exchange,提问作者Malak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 14:54:52