PesaThe
PesaThe

Reputation: 7499

Why does TextField lose focus when views are added around it?

I have a simple screen with a TextField. There is one info text above it and one below it. Those info texts are displayed only when a certain condition is met.

Minimal example:

class FooPage extends StatefulWidget {
  const FooPage({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return FooState();
  }
}

class FooState extends State<FooPage> {
  TextEditingController controller = TextEditingController();
  bool show = true;
  
  @override
  void initState() {
    super.initState();
    controller.addListener(() {
      setState(() => show = controller.text.length < 5);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          show ? const Text("hello1") : const SizedBox.shrink(),
          TextField(controller: controller),
          show ? const Text("hello2") : const SizedBox.shrink(),
        ],
      ),
    );
  }
}

The problem is that when the info texts either appear or disappear, the TextField loses focus! If I use just one text (either of them), everything works fine.


I can solve this by wrapping the info texts with ExcludeFocus or using autoFocus: true on the TextField. But I am pretty sure those are not good solutions. At least the latter one can't be :)

What is happening here? What is the proper way to solve this?

Upvotes: 4

Views: 2339

Answers (1)

Ozan Taskiran
Ozan Taskiran

Reputation: 3552

I can't tell you why my solution works, but if you pass a GlobalKey to the TextField, it won't lose its focus.

GlobalKey globalKey = GlobalKey();


TextField(controller: controller, key: globalKey,),

Maybe something to do with this? From the docs:

Widgets that have global keys reparent their subtrees when they are moved from one location in the tree to another location in the tree. In order to reparent its subtree, a widget must arrive at its new location in the tree in the same animation frame in which it was removed from its old location in the tree.

Upvotes: 6

Related Questions