Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextField widgets lose focus (Flutter)

I am creating an app with Flutter TextField widgets:

class CategoryData {
  int? id;
  String name;
  String description;

  CategoryData({this.id, required this.name, required this.description});
}

class CategoriesEdit extends StatefulWidget {
  Database? db;
  CategoryData? category;

  CategoriesEdit({super.key, required this.db, required this.category});

  @override
  State<StatefulWidget> createState() => CategoriesEditState();
}

class CategoriesEditState extends State<CategoriesEdit> {
  CategoryData? category;

  void saveState(BuildContext context) {
    // ...
  }

  @override
  Widget build(BuildContext context) {
    if (category == null) {
      setState(() {
        category = widget.category ?? CategoryData(name: "", description: "");
      });
    }

    return Scaffold(
        appBar: AppBar(
          leading: InkWell(
              child: const Icon(Icons.arrow_circle_left),
              onTap: () => Navigator.pop(context)),
          title: const Text("Edit Category"),
        ),
        body: Column(children: [
          Column(key: const Key('name'), children: [
            const Text("Category name:*"),
            TextField(
                controller: TextEditingController(text: category!.name),
                onChanged: (value) {
                  setState(() {
                    category!.name = value;
                  });
                })
          ]),
          Column(key: const Key('description'), children: [
            const Text("Description:"),
            TextField(
                controller: TextEditingController(text: category!.description),
                onChanged: (value) {
                  setState(() {
                    category!.description = value;
                  });
                })
          ]),
          Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
            ElevatedButton(
              onPressed: () => saveState(context), // passing false
              child: const Text('OK'),
            ),
            OutlinedButton(
              onPressed: () => Navigator.pop(context, false),
              // passing false
              child: const Text('Cancel'),
            ),
          ]),
        ]));
  }
}

But after I type a character in one of these two widgets, the cursor moves before the first character and the Android keyboard widget disappears. Why? And how to fix that bug?

I tried adding widget keys, but as you see it didn't help.

like image 604
porton Avatar asked Sep 01 '26 18:09

porton


1 Answers

There is a lot of things going wrong here, not only the stuff mentioned in the other answer.

  1. Move the setState in the builder into initState:

    if (category == null) {
      setState(() {
        category = widget.category ?? CategoryData(name: "", description: "");
      });
    }
    
  2. Don't use setState in the onChanged callback. Change:

    onChanged: (value) {
      setState(() {
        category!.description = value;
      });
    }
    

    to this:

    onChanged: (value) {
      category!.description = value;
    }
    
  3. Store the TextEditingControllers, because you have to dispose them once we dispose the state.

  4. If you are already using TextEditingControllers, then you don't need the onChanged callback. Just take text from the controller like explained in the other answer.

like image 161
TripleNine Avatar answered Sep 03 '26 08:09

TripleNine



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!