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,可以避免初始值与状态变量不同步的问题,示例如下:
- 定义控制器:
final TextEditingController _nameController = TextEditingController();
- 在
initState中初始化:
@override void initState() { super.initState(); _nameController.text = widget.name; }
- 绑定到TextFormField:
TextFormField( controller: _nameController, // ...其他属性 onChanged: (value) { setState(() {}); // 只需触发UI重建即可 }, )
- 条件判断改为:
(_nameController.text.trim() != widget.name) ? TextButton(...) : const SizedBox.shrink()
这样可以更直观地管理输入框内容,减少状态变量维护的复杂度。
内容的提问来源于stack exchange,提问作者Mateus Neves
相关产品推荐
相关产品推荐

