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

Flutter问题:值变更后UI未更新,目标按钮无法显示

问题解决:TextFormField值变化后AppBar按钮不显示的修复

问题原因

你当前的代码中,在TextFormField的onChanged回调里更新了状态变量name,但没有调用setState()通知Flutter框架重新构建UI。这导致AppBar中的条件判断name != widget.name始终使用初始值,按钮无法根据输入变化显示。

修复方案

在onChanged回调中更新name后,调用setState()触发UI重建:

onChanged: (value) {
  setState(() {
    name = value.trim();
  });
  print(name);
  print('widget ${widget.name}');
},

修改后的完整代码

class ViewPatientPage extends StatefulWidget {
  final int status;
  final String name;
  const ViewPatientPage({required this.status, required this.name, super.key});

  @override
  State<ViewPatientPage> createState() => _ViewPatientPageState();
}

class _ViewPatientPageState extends State<ViewPatientPage> {
  String name = '';
  @override
  void initState() {
    super.initState();
    name = widget.name;
  }

  SizedBox space() {
    return const SizedBox(height: 15);
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        FocusManager.instance.primaryFocus?.unfocus();
      },
      child: Scaffold(
        appBar: AppBar(
          actions: [
           (name != widget.name) ? TextButton(
                onPressed: () {},
                child: const Text(
                  'Editar',
                  style: TextStyle(color: Colors.white),
                )): const SizedBox.shrink()
          ],
        ),
        body: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 10),
          child: Column(
            children: [
              space(),
              TextFormField(
                initialValue: widget.name,
                validator: (val) {
                  if (val.toString().isEmpty || val == null || val == '') {
                    return 'Fill field';
                  }
                  return null;
                },
                decoration: InputDecoration(
                    label: const Text('Name'),
                    contentPadding: const EdgeInsets.symmetric(horizontal: 20),
                    border: OutlineInputBorder(
                        borderSide: const BorderSide(color: Colors.black),
                        borderRadius: BorderRadius.circular(20))),
                onChanged: (value) {
                  setState(() {
                    name = value.trim();
                  });
                  print(name);
                  print('widget ${widget.name}');
                },
              ),
              space(),
            ],
          ),
        ),
      ),
    );
  }
}

额外建议

对于输入框内容管理,更规范的方式是使用TextEditingController,可以避免初始值与状态变量不同步的问题,示例如下:

  1. 定义控制器:
final TextEditingController _nameController = TextEditingController();
  1. 在initState中初始化:
@override
void initState() {
  super.initState();
  _nameController.text = widget.name;
}
  1. 绑定到TextFormField:
TextFormField(
  controller: _nameController,
  // ...其他属性
  onChanged: (value) {
    setState(() {}); // 只需触发UI重建即可
  },
)
  1. 条件判断改为:
(_nameController.text.trim() != widget.name) ? TextButton(...) : const SizedBox.shrink()

这样可以更直观地管理输入框内容,减少状态变量维护的复杂度。

内容的提问来源于stack exchange,提问作者Mateus Neves

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:10:18