Flutter - modalBottomSheet 中 StatefulBuilder 中的 TextField 不工作
Flutter - TextField in StatefulBuilder in modalBottomSheet not working
我有问题。在我的代码中,我调用 showModalBottomSheet
并且在其中,我有一个反馈表。用户可以 select 反应,然后发表评论以提交。
因此,我不得不使用 StatefulBuilder
在模态中使用 setState
。但是 TextField
有一个奇怪的行为——当我点击它时,键盘会出现一瞬间,然后模态框会重置为原始状态。如果我删除 StatefulBuilder
并将 GestureDetector
保留为主小部件,一切都会按预期工作(键盘出现,模态移动以显示它,等等)。
有什么办法可以让StatefulBuilder
和TextField
共存吗?下面有一段代码,经过适当删减以重点解决这个问题。
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: ...,
),
),
),
),
);
},
);
谢谢!
你可以试试下面的代码
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: ...,
),
),
),
),
);
},
);
或者您可以尝试将其设为另一个 StatefulWidget
,例如关注
showModalBottomSheet<void>(
context: context,
isScrollControlled: true, // makes content maxHeight = full device height
builder: (BuildContext context) {
return YourRefactoredStatefulWidget();
}
.....
我有问题。在我的代码中,我调用 showModalBottomSheet
并且在其中,我有一个反馈表。用户可以 select 反应,然后发表评论以提交。
因此,我不得不使用 StatefulBuilder
在模态中使用 setState
。但是 TextField
有一个奇怪的行为——当我点击它时,键盘会出现一瞬间,然后模态框会重置为原始状态。如果我删除 StatefulBuilder
并将 GestureDetector
保留为主小部件,一切都会按预期工作(键盘出现,模态移动以显示它,等等)。
有什么办法可以让StatefulBuilder
和TextField
共存吗?下面有一段代码,经过适当删减以重点解决这个问题。
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: ...,
),
),
),
),
);
},
);
谢谢!
你可以试试下面的代码
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: ...,
),
),
),
),
);
},
);
或者您可以尝试将其设为另一个 StatefulWidget
,例如关注
showModalBottomSheet<void>(
context: context,
isScrollControlled: true, // makes content maxHeight = full device height
builder: (BuildContext context) {
return YourRefactoredStatefulWidget();
}
.....