背景: 我正在制作一个基本的 taskApp,我有一个 addTaskFormView,它有用于任务标题和描述的子 textField 小部件。每个 textField 小部件都在它们自己的文件中,我从我的 addTaskFormView 传递一个回调函数,它将在我的 addTaskFormView 中设置一些 textEditingControllers 的状态。
问题: 当用户通过单击屏幕上的其他位置离开文本字段时,我想获取这些文本字段的值。
为此,我将我的 textField 包装在一个 Focus 小部件中,并将我的回调函数称为 onFocusChange。
我的父级 addTaskFormView 在单击调用 FocusScope.of(context).unfocus() 时有一个提交按钮,这应该会触发 onFocusChange。
但是,我发现我没有获得对 textFields 的最新更改。我必须单击提交按钮两次才能注册最新的更改。 例如,如果我输入标题“first”,然后单击“提交”,我什么也得不到。如果我输入“second”然后再次单击按钮,我会得到“first”。
代码
addTaskFormView.dart
class addTaskFormView extends StatefulWidget {
var taskIdentifier;
final TextEditingController titleController = TextEditingController();
final TextEditingController descController = TextEditingController();
addTaskFormView({Key? key, this.taskIdentifier});
@override
State<addTaskFormView> createState() => _addTaskFormViewState();
}
class _addTaskFormViewState extends State<addTaskFormView> {
String taskTitle = '';
String description ='';
var viewModelAddTask;
@override
void initState() {
super.initState();
viewModelAddTask = Provider.of<addTaskFormViewModel>(context, listen: false);
}
@override
Widget build(BuildContext context) {
setTitle(String? value) {
print("CALL BACK HAS BEEN CALLED");
setState(() {
this.taskTitle = value!;
widget.titleController.text = value;
});
}
setDescription(String? value) {
setState(() {
this.description = value!;
widget.descController.text = value;
});
}
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
appBar: AppBar(
title: const Text('Add a new task'),
),
body: Column(
children:[
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
buildTaskTitle(
callBackFunction: setTitle,
titleController: widget.titleController,
),
buildTaskDesc(
callBackFunction: setDescription,
descController: widget.descController
),
ElevatedButton(onPressed: (){
//submit data to hive
FocusScope.of(context).unfocus();
print("task title: $taskTitle");
print("task title: $description");
}, child: const Text('Submit'))
]
),
),
]
),
),
);
}
}
buildTaskDesc.dart
class buildTaskDesc extends StatefulWidget {
const buildTaskDesc({Key? key, required this.callBackFunction, required this.descController});
final Function callBackFunction;
final TextEditingController descController;
@override
State<buildTaskDesc> createState() => _buildTaskDescState();
}
class _buildTaskDescState extends State<buildTaskDesc> {
String description = '';
@override
Widget build(BuildContext context) {
return Focus(
canRequestFocus: false,
onFocusChange: (hasFocus) {
hasFocus ? print('title has focus') : widget.callBackFunction(widget.descController.text);
},
child: TextField(
key: const Key('task_description'),
controller: widget.descController,
decoration: InputDecoration(
labelText: 'Description',
hintText: 'Enter task description',
border: const OutlineInputBorder(),
suffixIcon: widget.descController.text.isEmpty
? Container(width: 0)
: IconButton(
icon: const Icon(Icons.close),
onPressed: () => widget.descController.clear(),
),
),
style: const TextStyle(fontSize: 14),
maxLines: 15,
minLines: 7,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
),
);
}
}
额外:
没有包含 buildTaskTitle,因为它与 buildTaskDesc 基本相同。如果需要,我可以稍后包含它。
我尝试用手势检测器包裹脚手架并使用 onTap 方法取消聚焦,但我遇到了同样的问题。
我还尝试了另一个 StackOverflow 答案并将手势检测器包裹在我的 elevatedButton 中,并使用 onTap 方法调用 unfocus,但结果相同。