简体   繁体   中英

setState hold focus and keyboard visibility

I tried to create something like the textfield widget in the gif below. I listen to the controller for changes and call setState(). I choose between two widgets depending on the controller.text.isEmpty. The problem is whenever setState is called the textField loses focus and the keyboard disappears. How do I stop this from happening?

Widget textInputInactive = Padding(
  padding: const EdgeInsets.all(8.0),
  child: Row(
    children: [
      IconButton(onPressed: () {}, icon: Icon(Icons.camera_alt, size: 28, color: Color(0xff99999A),)),
      IconButton(onPressed: () {}, icon: Icon(Icons.upload_file, size: 28, color: Color(0xff99999A),)),
      Expanded(
        child: textField
      ),
    ],
  ),
);

Widget textInputActive = Padding(
  padding: const EdgeInsets.all(8.0),
  child: Row(
    children: [
      Expanded(child: textField),
      IconButton(onPressed: () {}, icon: Icon(Icons.send, color: Color(0xff99999A)))
    ],
  ),
);

Widget currTextInput = _textController.text.isNotEmpty ? textInputActive : textInputInactive;

动图

If you need the keyboard to gain focus after the setState method is called. You need to create a focus node object and initialize it in your initState, and add it as a parameter to your focus node in the textfield. Then after you call setState, request focus, here is an example below.

class MyWidget extends StatefulWidget {
  const MyWidget({super.key});

@override
 State<MyWidget> createState() => _MyWidgetState();
 }

class _MyWidgetState extends State<MyWidget> {
 // create the FocusNode object
 FocusNode node = FocusNode();

@override
void initState() {
 super.initState();
 // request focus of the textfield
 node.requestFocus();
}

@override
void dispose() {
 // disposing it
 node.dispose();
 super.dispose();
}

@override
Widget build(BuildContext context) {
// assume this is where you call your setState
// to call back focus on the textfield
setState(() {});
node.requestFocus();

return TextField(
  // add the node object here
  focusNode: node,
  );
 }
}

You can try to use Value Notifier instead of setState, since setState will render the whole page and create a new focus node. check this link for value notifier and use it only for text filed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM