onFocusChange 不捕获 Flutter 中 textField 的最新更改

问题描述 投票:0回答:0

背景: 我正在制作一个基本的 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,但结果相同。

android flutter user-interface focus
© www.soinside.com 2019 - 2024. All rights reserved.