I’m making a dynamic input form using flutter_bloc
to manage form states.
I can add and remove the TextFormField
.
The problem is inputs keep losing focus immediately after typing a word.
I understand that BlocSelector
rebuilds its content when selected state is changed but I do not know how to persist the key for each input since my TextFormField
s are dynamic
My code
class AddQuestionScreenBody extends StatelessWidget {
AddQuestionScreenBody({super.key});
final GlobalKey _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(right: 15.0, left: 15.0),
child: Form(
key: _formKey,
child: Column(
children: [
BlocSelector<AddQuestionBloc, AddQuestionState, List<String>>(
selector: (state) => state.answerList,
builder: (context, answerList) {
return Column(
children: [
for (int i = 0; i < answerList.length; i++)
Padding(
padding: const EdgeInsets.only(bottom: 15.0),
child: TextFormField(
key: UniqueKey(),
initialValue: answerList[i],
validator: (value) {
if (value == null || value.isEmpty) {
return "Answer is required";
}
return null;
},
onChanged: (value) {
context.read<AddQuestionBloc>().add(
OnChangeAnswerElement(
index: i,
value: value,
),
);
},
decoration: InputDecoration(
label: Text('Answer ${i + 1}'),
suffixIconColor: Colors.redAccent,
suffixIcon: IconButton(
onPressed: () {
context.read<AddQuestionBloc>().add(
OnRemoveAnswerElement(
i));
},
icon: const Icon(Icons.remove),
),
),
),
),
ElevatedButton(
onPressed: () {
context.read<AddQuestionBloc>().add(
OnAddAnswerElement(),
);
},
child: const Icon(Icons.add),
),
],
);
},
),
],
),
),
);
}
}
How can I solve this issue?
2
Answers
I found the root cause, BlocSelector rebuilds widget tree so the TextFormField will lose its key since I'm using
Unikey()
as the key.The solution is to create my own key for each TextFormField so I can persist the key regardless of Widget tree getting rebuilt.
You should provide AddQuestionBloc to see do you rebiuld screen on every change by doing:
And as you have TextFormField, may be you should rebuild hole screen on form submition only with onFieldSubmitted callback?
Also, try to set FocusNode() for each TextFormField.
So you need defferent keys, focus nodes and may be controllers for each TextFormField. It depends on your requierments.