使用 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),
);
}
上面的方法返回一个 TextField,用于在表单内显示两个文本字段。
Form(
children:[_getSourceAndOriginTextField('Origin',controller),
SizedBox(height:10),
_getSourceAndOriginTextField('Origin',controller)])
当我点击其中一个文本字段时,状态会发生变化,对话框会打开,但对话框会显示两次。我在这里缺少什么?
以下是供参考的图像,任何帮助将不胜感激。
I have 2 textFields that have a gesture detector and on tap of the gesture detector, I open an AlertDialog using the BlocListener widget.
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),
);
}
This method above which returns a TextField is being used inside the form to display two textfields.
Form(
children:[_getSourceAndOriginTextField('Origin',controller),
SizedBox(height:10),
_getSourceAndOriginTextField('Origin',controller)])
When I tap on one of the textfields the state changes and the dialog opens but the dialog is displayed twice. What am I missing here?
Following are the images for reference, any help will be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
和
基本上可以解释你的问题。由于您执行了
_getSourceAndOriginTextField()
两次,因此您还创建了两次BlocListener(...)
。因此,当PortsCubit
状态更改为PortsLoadedState
时,两个侦听器都会触发showDialog
函数。您可以做的就是提升
BlocListener
并用它包装Form
。这样,您将只有一个可以打开对话框的侦听器:and
basically explains your problem. Since you are executing
_getSourceAndOriginTextField()
twice, you also create theBlocListener<PortsCubit, PortsState>(...)
twice. Thus, when thePortsCubit
state changes toPortsLoadedState
, both listeners trigger theshowDialog
function.What you can do is lift the
BlocListener
and wrap theForm
with it. This way you will have only a single listener that could open the dialog: