Flutter TextField如何检测文本字段未聚焦但未提交?

mzsu5hc0  于 2023-03-31  发布在  Flutter
关注(0)|答案(1)|浏览(131)

我想使用一个TextField允许用户在应用程序中重命名一个项目。我想为新的项目名称被保存,如果用户按下键盘上的“完成”按钮,但我也想为应用程序对待用户unfocusingTextField没有按下完成按钮,这意味着用户取消了行动,项目名称应恢复到以前的名称。有没有一种方法可以只在文本提交时调用unfocus上的函数?

ne5o7dgx

ne5o7dgx1#

您可以使用Flutter中的FocusNode类来实现这一点。

class RenameItemWidget extends StatefulWidget {
  const RenameItemWidget({required this.initialName, this.onSave});

  final String initialName;
  final void Function(String value)? onSave;

  @override
  State<RenameItemWidget> createState() => _RenameItemWidgetState();
}

class _RenameItemWidgetState extends State<RenameItemWidget> {
  late TextEditingController _textEditingController;
  late FocusNode _focusNode;
  late String _itemName;

  @override
  void initState() {
    super.initState();

    _textEditingController = TextEditingController(text: widget.initialName);

    _focusNode = FocusNode();
    _itemName = widget.initialName;

    _focusNode.addListener(_onFocusChange);
  }

  @override
  void didUpdateWidget(RenameItemWidget oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (oldWidget.initialName != widget.initialName) {
      _textEditingController.text = widget.initialName;
      _itemName = widget.initialName;
    }
  }

  @override
  Widget build(BuildContext context) => TextField(
        controller: _textEditingController,
        focusNode: _focusNode,
        decoration: const InputDecoration(labelText: 'Item name'),
        onSubmitted: (_) => _saveName(),
      );

  void _onFocusChange() {
    if (!_focusNode.hasFocus && _textEditingController.text != _itemName) {
      setState(() => _textEditingController.text = _itemName);
    }
  }

  void _saveName() {
    setState(() => _itemName = _textEditingController.text);

    widget.onSave?.call(_itemName);
  }

  @override
  void dispose() {
    _textEditingController.dispose();
    _focusNode.dispose();

    super.dispose();
  }
}

相关问题