首页 > 解决方案 > TextField 使用 setState 失去焦点

问题描述

我有一个习惯StatefulWidget,当输入一个空字段时,它会自动在下面添加一个新的空字段,以便用户可以继续添加数据。

但是,当我使用setStateinonChanged添加新字段时,键盘被关闭并且焦点丢失在当前聚焦的字段上。

Io 如何防止这种情况发生?

 TextField(
          hintText: widget.newEntryHint,
          text: data[index].value,
          onChanged: (val) {
            setState(() {
              data[index].value = val;
    
              //if last item in list, add an extra field below
              if (val.length > 0 && index == (data.length -1)) {
                data.add(TextListItem(value: ""));
              }
            });
          },
        )

自定义 TextField 供参考:

class MyTextField extends StatefulWidget {
  MyTextField({
    this.text,
    this.hintText = "",
    this.onChanged,
    this.onSubmitted,
    this.textAlign = TextAlign.left,
    this.focusNode,
    this.autofocus = false,
    this.obscureText = false,
    this.padding = const EdgeInsets.all(0.0),
    this.keyboardType = TextInputType.text,
    this.canEdit = true,
    this.isDarkMode = false,
    this.textCapitalization = TextCapitalization.sentences,
    this.key,
  });

  final String text;
  final String hintText;
  final ValueChanged<String> onChanged;
  final ValueChanged<String> onSubmitted;
  final TextAlign textAlign;
  final FocusNode focusNode;
  final bool autofocus;
  final bool obscureText;
  final EdgeInsets padding;
  final TextInputType keyboardType;
  final TextCapitalization textCapitalization;
  final Key key;

  final bool canEdit;

  final isDarkMode;

  @override
  _MyTextFieldState createState() => _MyTextFieldState();
}

class _MyTextFieldState extends State<MyTextField> {
  static const double textFieldPadding = 12.0;
  TextEditingController editingController;

  @override
  void initState() {
    super.initState();
    editingController = TextEditingController(text: widget.text);
  }

  @override
  Widget build(BuildContext context) {
    return IgnorePointer(
      ignoring: !widget.canEdit,
      child: Column(
        children: <Widget>[
          Padding(
            padding: EdgeInsets.only(
                top: textFieldPadding + widget.padding.top, bottom: textFieldPadding + widget.padding.bottom, left: widget.padding.left, right: widget.padding.right),
            child: TextField(
              key: widget.key,
              maxLines: null,
              textCapitalization: widget.textCapitalization,
              keyboardType: widget.keyboardType,
              keyboardAppearance: widget.isDarkMode ? Brightness.dark : Brightness.light,
              controller: editingController,
              onSubmitted: widget.onSubmitted,
              onChanged: widget.onChanged,
              style: TextStyle(
                  color: widget.isDarkMode ? Colors.white : MyColors.textBlue,
                  fontSize: 16.0,
                  fontWeight: FontWeight.w500),
              autofocus: widget.autofocus,
              focusNode: widget.focusNode,
              textAlign: widget.textAlign,
              obscureText: widget.obscureText,
              decoration: InputDecoration(
                hintText: widget.hintText,
                hintStyle: TextStyle(
                    color: widget.isDarkMode ? MyColors.black[700] : MyColors.grey,
                    fontSize: 16.0,
                    fontWeight: FontWeight.w500),
                border: InputBorder.none,
              ),
            ),
          ),
          Divider(
            color: widget.isDarkMode ? MyColors.black : MyColors.grey[150],
            height: 1.0,
          ),
        ],
      ),
    );
  }
}

标签: flutterkeyboardfocustextfield

解决方案


我曾经也有过一样的问题。我发现我key: UniqueKey()在我的容器中使用。在每一个setState它生成uniqueKey和更新孩子。检查你的钥匙。


推荐阅读