I have a problem. In my code, I call showModalBottomSheet
and inside of it, I have a feedback form. The user can select a reaction and then leave a comment to submit.
Therefore, I had to use a StatefulBuilder
to use setState
inside the modal. The TextField
has a weird behavior though—when I click on it, the keyboard appears for an instant and then the modal is reset to the original state. If I remove the StatefulBuilder
and I leave the GestureDetector
as main Widget, everything works as expected (the keyboard appears, the modal moves to show it, and so on).
Is there any way to make the StatefulBuilder
and the TextField
coexist? Below there is a snippet of code, appropriately cut to focus on this problem.
TextEditingController feedbackTextFieldController = TextEditingController();
...
showModalBottomSheet<void>(
context: context,
isScrollControlled: true, // makes content maxHeight = full device height
builder: (BuildContext context) {
bool _isFeedbackLoading = false;
return StatefulBuilder(
builder: (context, setState) => GestureDetector(
onTap: () {
// the following is needed to dismiss the keyboard on tap outside of it
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: AnimatedPadding(
// to make the modal move when the keyboard is shown
padding: MediaQuery.of(context).viewInsets,
duration: const Duration(milliseconds: 100),
curve: Curves.decelerate,
child: Container(
child: _isFeedbackLoading
? Center(
child: CircularProgressIndicator(),
)
: TextField(
controller: feedbackTextFieldController,
textInputAction: TextInputAction.done,
textCapitalization: TextCapitalization.sentences,
maxLines: 2,
style: ...,
decoration: ...,
),
),
),
),
);
},
);
Thank you!
CodePudding user response:
you can give try to following code
showModalBottomSheet<void>(
context: context,
isScrollControlled: true, // makes content maxHeight = full device height
builder: (BuildContext context) {
bool _isFeedbackLoading = false;
return StatefulBuilder(
// it could also because of you may reaching the wrong context
// builder: (context, setState) => GestureDetector(
builder: (_, setState) => GestureDetector(
// may be you are not able to tap
behavior: HitTestBehavior.opaque,
onTap: () {
// the following is needed to dismiss the keyboard on tap outside of it
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: AnimatedPadding(
// to make the modal move when the keyboard is shown
padding: MediaQuery.of(context).viewInsets,
duration: const Duration(milliseconds: 100),
curve: Curves.decelerate,
child: Container(
child: _isFeedbackLoading
? Center(
child: CircularProgressIndicator(),
)
: TextField(
controller: feedbackTextFieldController,
textInputAction: TextInputAction.done,
textCapitalization: TextCapitalization.sentences,
maxLines: 2,
style: ...,
decoration: ...,
),
),
),
),
);
},
);
or you can try to make it another StatefulWidget
for this, like following
showModalBottomSheet<void>(
context: context,
isScrollControlled: true, // makes content maxHeight = full device height
builder: (BuildContext context) {
return YourRefactoredStatefulWidget();
}
.....