flutter - 使用 BlocListener 显示对话框

标签 flutter dart bloc state-management flutter-bloc

我有 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)])

当我点击其中一个文本字段时,状态会发生变化,对话框会打开,但对话框会显示两次。我在这里缺少什么?

以下是供引用的图片,任何帮助将不胜感激。

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)]) 
},

关于flutter - 使用 BlocListener 显示对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71365902/

相关文章:

firebase - 如何将photoUrl添加到当前用户?

forms - 什么是 copyWith 以及如何在 Flutter 中使用它以及它的用例是什么?

flutter - 如何在屏幕加载时只调用一次 bloc 事件

使用 Agora Flutter 来电视频/音频调用通知

flutter - 如何在列中使用 FractionallySizedBox?

flutter - 防止从外部触摸隐藏 showModalBottomSheet

flutter - 如何在 flutter/Dart block 中取消 'await for'

Flutter:未处理的异常:错误状态:调用关闭后无法添加新事件(不同情况)

android-studio - 等待应用程序在 flutter 中启动超时(android studio)

dart - 如何在 AppBar 上制作圆形个人资料图片(操作按钮)