使用我当前的代码,TextField成为焦点,但是没有触发光标和键盘(需要再次点击)。我相信这是因为当焦点最初聚焦时,TextField不存在,但是我一直在努力寻找解决方案。
以下是根据菜谱食谱对问题的简单再现:
class MyCustomForm extends StatefulWidget {
@override
_MyCustomFormState createState() => _MyCustomFormState();
}
class _MyCustomFormState extends State<MyCustomForm> {
FocusNode myFocusNode;
bool _editingField2 = false;
@override
void initState() {
super.initState();
myFocusNode = FocusNode();
myFocusNode.addListener(_focusListener);
}
@override
void dispose() {
myFocusNode.dispose();
super.dispose();
}
// Set _editingField2 to true when focusNode has focus.
_focusListener() {
if (myFocusNode.hasFocus) {
setState(() {
_editingField2 = true;
});
} else {
setState(() {
_editingField2 = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Text Field Focus'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
// The first text field is focused on as soon as the app starts.
TextField(
autofocus: true,
),
// The second text field is created when _editingField2 (after FAB press).
_editingField2
? TextField(
focusNode: myFocusNode,
)
: Text('ayy'),
],
),
),
floatingActionButton: FloatingActionButton(
// Give focus node focus on FAB press.
onPressed: () => FocusScope.of(context).requestFocus(myFocusNode),
tooltip: 'Focus Second Text Field',
child: Icon(Icons.edit),
),
);
}
}
这是我的代码,其中有重要注释。
class TaskListItem extends StatefulWidget {
final Task task;
TaskListItem({@required this.task});
@override
State createState() => _TaskListItemState();
}
class _TaskListItemState extends State<TaskListItem> {
bool _isEditing;
FocusNode _focusNode;
final TextEditingController _textEditingController = TextEditingController();
@override
initState() {
super.initState();
_isEditing = false;
_textEditingController.text = widget.task.text;
_textEditingController.addListener(_handleTextFieldUpdate);
_focusNode = FocusNode(debugLabel: 'TaskListItem');
_focusNode.addListener(_handleFocusChange);
}
@override
void dispose() {
_focusNode.removeListener(_handleFocusChange);
_focusNode.dispose();
_textEditingController.dispose();
super.dispose();
}
_handleTextFieldUpdate() {
Provider.of<TaskListModel>(context, listen: false)
.updateTaskText(widget.task, _textEditingController.text);
}
// Update state to determine if Text or TextField widget is created in build().
_handleFocusChange() {
if (_focusNode.hasFocus) {
setState(() {
_isEditing = true;
});
} else {
setState(() {
_isEditing = false;
});
}
}
Widget _buildTitle() {
return Row(
children: <Widget>[
Expanded(
// Create either TextField or Text based on _isEditing value.
child: _isEditing && !widget.task.isComplete
? TextField(
focusNode: _focusNode,
controller: _textEditingController,
)
: Text(
widget.task.text,
style: widget.task.isComplete
? TextStyle(decoration: TextDecoration.lineThrough)
: null,
),
),
],
);
}
@override
Widget build(BuildContext context) {
return ListTile(
leading: Checkbox(
value: widget.task.isComplete,
//Dismiss focus when box is checked
onChanged: (bool checked) {
_focusNode.unfocus();
Provider.of<TaskListModel>(context, listen: false)
.toggleComplete(widget.task);
},
),
title: _buildTitle(),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => Provider.of<TaskListModel>(context, listen: false)
.deleteTask(widget.task),
),
onTap: () {
// I'm requesting focus here, but the Textfield doesn't exist yet?
FocusScope.of(context).requestFocus(_focusNode);
print('tapped');
},
);
}
}
答案 0 :(得分:0)
您需要做的是在构建中更改焦点,您要在屏幕完成重建该窗口小部件之前尝试更改焦点。请使用您自己的代码尝试这个。
我不确定您是否真的需要收听焦点更改,还是只想在启用小部件后完成焦点更改,如果您确实想收听焦点更改,请告诉我。
class MyCustomForm extends StatefulWidget {
@override
_MyCustomFormState createState() => _MyCustomFormState();
}
class _MyCustomFormState extends State<MyCustomForm> {
FocusNode myFocusNode = FocusNode();
bool _editingField2 = false;
@override
void dispose() {
myFocusNode?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
//here you do the focus request
if (_editingField2) {
FocusScope.of(context).requestFocus(myFocusNode);
}
return Scaffold(
appBar: AppBar(
title: Text('Text Field Focus'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
// The first text field is focused on as soon as the app starts.
TextField(
autofocus: true,
),
// The second text field is created when _editingField2 (after FAB press).
_editingField2
? TextField(
focusNode: myFocusNode,
)
: Text('ayy'),
],
),
),
floatingActionButton: FloatingActionButton(
// Give focus node focus on FAB press.
onPressed: () {
setState(() {
_editingField2 = true;
});
},
tooltip: 'Focus Second Text Field',
child: Icon(Icons.edit),
),
);
}
}