Flutter TextField如何检测未提交就失去焦点的情况?
实现TextField项目重命名的提交/取消逻辑
当然可以实现这个需求,核心是用一个布尔标记区分用户是否通过「done」按钮提交了输入,失焦时根据这个标记判断是否要恢复原始名称。以下是具体的Flutter实现示例:
import 'package:flutter/material.dart'; class RenameItemPage extends StatefulWidget { final String originalName; final Function(String) onSave; const RenameItemPage({ super.key, required this.originalName, required this.onSave, }); @override State<RenameItemPage> createState() => _RenameItemPageState(); } class _RenameItemPageState extends State<RenameItemPage> { late TextEditingController _controller; late FocusNode _focusNode; // 标记是否已通过done按钮提交输入 bool _isSubmitted = false; late String _originalName; @override void initState() { super.initState(); _originalName = widget.originalName; _controller = TextEditingController(text: _originalName); _focusNode = FocusNode(); // 监听失焦事件 _focusNode.addListener(() { if (!_focusNode.hasFocus && !_isSubmitted) { // 未提交就失焦,恢复原始名称 setState(() { _controller.text = _originalName; }); } }); } @override void dispose() { _controller.dispose(); _focusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('重命名项目')), body: Padding( padding: const EdgeInsets.all(16.0), child: TextField( controller: _controller, focusNode: _focusNode, autofocus: true, textInputAction: TextInputAction.done, onSubmitted: (newName) { // 点击done按钮,标记为已提交并保存 _isSubmitted = true; widget.onSave(newName); Navigator.pop(context); }, // 点击外部区域触发失焦 onTapOutside: (event) { _focusNode.unfocus(); }, decoration: const InputDecoration( hintText: '输入新名称', border: OutlineInputBorder(), ), ), ), ); } }
关键逻辑说明:
- 初始化时记录原始项目名称,并给TextField设置初始值
- 用
_isSubmitted布尔变量标记用户是否通过「done」按钮提交了输入 - 通过
FocusNode监听失焦事件,当TextField失去焦点且_isSubmitted为false时,将输入框内容恢复为原始名称 onSubmitted回调会在用户按下键盘的「done」按钮时触发,这里标记提交状态并调用保存方法
这样就能精准区分两种场景:只有用户没按done就失焦时,才执行恢复原始名称的操作。
内容的提问来源于stack exchange,提问作者Kulpas
相关产品推荐
相关产品推荐

