Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextField Loses Focus with setState

I have a custom StatefulWidget that when typing into an empty field, it will automatically add a new empty field below so the user can keep adding data.

However, as I use setState in onChanged to add the new field, the keyboard is dismissed and focus is lost on the currently focused field.

How can Io prevent this happening?

 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: ""));
              }
            });
          },
        )

Custom TextField for reference:

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,
          ),
        ],
      ),
    );
  }
}
like image 865
Josh Kahane Avatar asked Feb 05 '19 12:02

Josh Kahane


People also ask

Why does the input field lose focus after typing a character?

it is because you are rendering the form in a function inside render(). Every time your state/prop change, the function returns a new form. it caused you to lose focus.

What is autofocus Flutter?

autofocus property Null safety bool autofocus. Whether this text field should focus itself if nothing else is already focused. If true, the keyboard will open as soon as this text field obtains focus. Otherwise, the keyboard is only shown after the user taps the text field. Defaults to false.


1 Answers

I have had the same problem. I have found that I use key: UniqueKey() in my container. On every setState it generates uniqueKey and updates the children. Check your keys.

like image 172
EvaNi Avatar answered Oct 05 '22 23:10

EvaNi