Home > Mobile >  Flutter - TextField in StatefulBuilder in modalBottomSheet not working
Flutter - TextField in StatefulBuilder in modalBottomSheet not working

Time:10-14

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();
    }
.....
  • Related