flutter 使用setState时TextField失去焦点

5jvtdoz2  于 2022-12-27  发布在  Flutter
关注(0)|答案(4)|浏览(336)

我有一个自定义的StatefulWidget,当输入一个空字段时,它会自动在下面添加一个新的空字段,这样用户就可以继续添加数据。
但是,当我在onChanged中使用setState添加新字段时,键盘被关闭,焦点在当前聚焦的字段上丢失。
木卫一如何防止这种情况发生?

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,
          ),
        ],
      ),
    );
  }
}
du7egjpx

du7egjpx1#

我也遇到过同样的问题。我发现我在我的容器中使用key: UniqueKey()。在每个setState上,它都会生成uniqueKey并更新孩子。检查你的密钥。

r6l8ljro

r6l8ljro2#

我知道已经有一段时间了,也许从那以后有些东西被修复了,但是我再也没有看到你的问题了。至少我设置你的小工具的方式(* 你的data.add()和我的fields.add()之间的细微差别 *)。

List<Widget> _fields;
ScrollController controller = new ScrollController();

_buildData() {
  _fields = new List();
  for (int i = 0; i < 3; i++) {
    _fields.add(_createMyTextField('hello$i', i));
  }
}

Widget _createMyTextField(String text, int index) {
  return MyTextField(
    text: text,
    hintText: 'hello hint$index',
    onChanged: (val) {
      setState(() {
        //if last item in list, add an extra field below
        if (val.length > 0 && index == (_fields.length-1)) {
          _fields.add(_createMyTextField("", index+1));
        }
      });
    },
  );
}

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

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text(widget.title)),
    body: ListView(
      controller: controller,
      children: _fields.toList()
    )
  );
}

ej83mcc0

ej83mcc03#

我最近遇到了同样的问题。我的问题是由树中的Container引起的,它有一个可选的margin,该margin由子树中的焦点控制。当点击TextFormField时,键盘会上下弹出,字段没有焦点。但是,由于焦点,容器的边距被正确更改。
通过将容器的边距从空值改为0,它修复了这个问题。它也可以应用于其他属性,如填充等。

mspsb9vt

mspsb9vt4#

在我的例子中,这个问题与TextFormField的键有关。
我在页面外创建了一个窗体键

final _formKey = GlobalKey<FormState>();

然后我把那个键作为一个参数给了textformfield

TextFormField(
              focusNode: textFormFieldFocusNode,
              key: _formKey,
              ....
              ....

我希望它能为这类问题提供一个视角。

相关问题