如何正确聚焦基于焦点节点的hasFocus值有条件创建的Textfield?

使用我当前的代码,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');
      },);
  }
}
qqleecs 回答:如何正确聚焦基于焦点节点的hasFocus值有条件创建的Textfield?

您需要做的是在构建中更改焦点,您要在屏幕完成重建该窗口小部件之前尝试更改焦点。请使用您自己的代码尝试这个。

我不确定您是否真的需要收听焦点更改,还是只想在启用小部件后完成焦点更改,如果您确实想收听焦点更改,请告诉我。

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),);
  }
}
本文链接:https://www.f2er.com/3091940.html

大家都在问