显示带有 BlocListener 的对话框
Showing a dialog with BlocListener
我有 2 个带有手势检测器的文本字段,点击手势检测器后,我使用 BlocListener 小部件打开了一个 AlertDialog。
Widget _getSourceAndOriginTextField(String hintText, controller) {
final portsCubit = BlocProvider.of<PortsCubit>(context);
return TextFormField(
controller: controller..text = "",
readOnly: true,
decoration: InputDecoration(
suffixIcon: GestureDetector(
onTap: () {
portsCubit.getAllPorts();
},
child: BlocListener<PortsCubit, PortsState>(
listenWhen: (previous, current) => previous != current,
listener: (context, state) async {
if (state is PortsLoadedState) {
await showDialog(
context: context,
builder: (_) => BlocProvider.value(
value: portsCubit,
child: PortsDialog(state.portsList),
));
}
},
child: SvgPicture.asset(
'assets/svg/chevron_down_icon.svg',
fit: BoxFit.scaleDown,
height: 10,
width: 18,
),
)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: Colors.transparent,
style: BorderStyle.solid,
width: 1,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
contentPadding: EdgeInsets.all(8),
hintText: hintText,
hintStyle: AppStyle.hintStyle),
);
}
此方法上面 returns 在表单内部使用了一个 TextField 来显示两个文本字段。
Form(
children:[_getSourceAndOriginTextField('Origin',controller),
SizedBox(height:10),
_getSourceAndOriginTextField('Origin',controller)])
当我点击其中一个文本字段时,状态发生变化并且对话框打开,但对话框显示了两次。我在这里错过了什么?
以下图片供参考,如有帮助将不胜感激。
TextField inside the form.
The AlertDialog
I have 2 textFields
和
This method above which returns a TextField is being used inside the form to display two textfields.
基本说明了你的问题。由于您正在执行 _getSourceAndOriginTextField()
两次,因此您还创建了 BlocListener<PortsCubit, PortsState>(...)
两次。因此,当 PortsCubit
状态变为 PortsLoadedState
时,两个侦听器都会触发 showDialog
函数。
你可以做的是提起 BlocListener
并用它包裹 Form
。这样您将只有一个可以打开对话框的侦听器:
BlocListener<PortsCubit, PortsState>(
listenWhen: (previous, current) => previous != current,
listener: (context, state) async {
if (state is PortsLoadedState) {
await showDialog(
context: context,
builder: (_) => BlocProvider.value(
value: portsCubit,
child: PortsDialog(state.portsList),
));
},
child: Form(
children:[_getSourceAndOriginTextField('Origin',controller),
SizedBox(height:10),
_getSourceAndOriginTextField('Origin',controller)])
},
我有 2 个带有手势检测器的文本字段,点击手势检测器后,我使用 BlocListener 小部件打开了一个 AlertDialog。
Widget _getSourceAndOriginTextField(String hintText, controller) {
final portsCubit = BlocProvider.of<PortsCubit>(context);
return TextFormField(
controller: controller..text = "",
readOnly: true,
decoration: InputDecoration(
suffixIcon: GestureDetector(
onTap: () {
portsCubit.getAllPorts();
},
child: BlocListener<PortsCubit, PortsState>(
listenWhen: (previous, current) => previous != current,
listener: (context, state) async {
if (state is PortsLoadedState) {
await showDialog(
context: context,
builder: (_) => BlocProvider.value(
value: portsCubit,
child: PortsDialog(state.portsList),
));
}
},
child: SvgPicture.asset(
'assets/svg/chevron_down_icon.svg',
fit: BoxFit.scaleDown,
height: 10,
width: 18,
),
)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: Colors.transparent,
style: BorderStyle.solid,
width: 1,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
contentPadding: EdgeInsets.all(8),
hintText: hintText,
hintStyle: AppStyle.hintStyle),
);
}
此方法上面 returns 在表单内部使用了一个 TextField 来显示两个文本字段。
Form(
children:[_getSourceAndOriginTextField('Origin',controller),
SizedBox(height:10),
_getSourceAndOriginTextField('Origin',controller)])
当我点击其中一个文本字段时,状态发生变化并且对话框打开,但对话框显示了两次。我在这里错过了什么?
以下图片供参考,如有帮助将不胜感激。
TextField inside the form.
The AlertDialog
I have 2 textFields
和
This method above which returns a TextField is being used inside the form to display two textfields.
基本说明了你的问题。由于您正在执行 _getSourceAndOriginTextField()
两次,因此您还创建了 BlocListener<PortsCubit, PortsState>(...)
两次。因此,当 PortsCubit
状态变为 PortsLoadedState
时,两个侦听器都会触发 showDialog
函数。
你可以做的是提起 BlocListener
并用它包裹 Form
。这样您将只有一个可以打开对话框的侦听器:
BlocListener<PortsCubit, PortsState>(
listenWhen: (previous, current) => previous != current,
listener: (context, state) async {
if (state is PortsLoadedState) {
await showDialog(
context: context,
builder: (_) => BlocProvider.value(
value: portsCubit,
child: PortsDialog(state.portsList),
));
},
child: Form(
children:[_getSourceAndOriginTextField('Origin',controller),
SizedBox(height:10),
_getSourceAndOriginTextField('Origin',controller)])
},