首页 > 解决方案 > 如何在 Flutter 中更改 BLoC 中的事件?

问题描述

我有一个创建 2FA totp 密钥的应用程序。当我在未填写表单时单击“添加”按钮时,它会显示一个警报对话框。如果我第二次单击它(仍然没有填写表单),则不会显示警报对话框。如何无限次显示警报对话框?我使用 BlocConsumer 来监听更改并在状态为 ManualInputError 时显示警报对话框,并使用 BlocBuilder 来显示实际的 TextButton。

图片

代码:

import 'dart:io';

import 'package:duckie/blocs/manual_input/manual_input_bloc.dart';
import 'package:duckie/screens/widgets/alert_dialog.dart';
import 'package:duckie/screens/widgets/custom_text_field.dart';
import 'package:duckie/shared/text_styles.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class ManualInputScreen extends StatefulWidget {
  @override
  _ManualInputScreenState createState() => _ManualInputScreenState();
}

class _ManualInputScreenState extends State<ManualInputScreen> {
  String secretKey;
  String issuer;
  String accountName;
  String numberOfDigits = '6';
  String timeStep = '30';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'manual-input',
          style: TextStyles.appBarText,
        ).tr(),
        centerTitle: true,
        elevation: 0.0,
        actions: [
          BlocConsumer<ManualInputBloc, ManualInputState>(
            listener: (context, state) {
              if (state is ManualInputError) {
                Platform.isAndroid
                    ? CustomAlertDialog.showAndroidAlertDialog(
                        context,
                        state.alertDialogErrorTitle,
                        state.alertDialogErrorContent)
                    : CustomAlertDialog.showIosAlertDialog(
                        context,
                        state.alertDialogErrorTitle,
                        state.alertDialogErrorContent);

                BlocProvider.of<ManualInputBloc>(context).close();
              }
            },
            builder: (context, state) {
              if (state is ManualInputInitial || state is ManualInputFinal) {
                return TextButton(
                  onPressed: () {
                    BlocProvider.of<ManualInputBloc>(context).add(
                        GetFormTextEvent(secretKey, issuer, accountName,
                            numberOfDigits, timeStep));
                  },
                  child: Text('add').tr(),
                );
              }
              return TextButton(
                onPressed: () {},
                child: Text('add').tr(),
              );
            },
          )
        ],
      ),
      body: Container(
        padding: EdgeInsets.all(8.0),
        child: ListView(
          children: [
            CustomTextField(
              labelText: 'secret-key'.tr(),
              onChanged: (value) {
                setState(() {
                  secretKey = value;
                });
              },
            ),
            SizedBox(
              height: 8.0,
            ),
            CustomTextField(
              labelText: 'issuer'.tr(),
              onChanged: (value) {
                issuer = value;
              },
            ),
            SizedBox(
              height: 8.0,
            ),
            CustomTextField(
              labelText: 'account-name'.tr(),
              onChanged: (value) {
                setState(() {
                  accountName = value;
                });
              },
            ),
            SizedBox(
              height: 8.0,
            ),
            Platform.isAndroid
                ? ListBody(
                    children: [
                      Text('number-of-digits').tr(),
                      SizedBox(
                        height: 5.0,
                      ),
                      DropdownButton(
                        value: numberOfDigits,
                        onChanged: (value) {
                          setState(() {
                            numberOfDigits = value;
                          });
                        },
                        items: [
                          DropdownMenuItem(
                            value: '6',
                            child: Text('6'),
                          ),
                          DropdownMenuItem(
                            value: '8',
                            child: Text('8'),
                          ),
                        ],
                      )
                    ],
                  )
                : ListBody(
                    children: [
                      Text('number-of-digits').tr(),
                      SizedBox(
                        height: 5.0,
                      ),
                      CupertinoSegmentedControl(
                        groupValue: numberOfDigits,
                        children: {
                          '6': Text('6'),
                          '8': Text('8'),
                        },
                        onValueChanged: (value) {
                          setState(() {
                            numberOfDigits = value;
                          });
                        },
                      ),
                    ],
                  ),
            SizedBox(
              height: 8.0,
            ),
            Platform.isAndroid
                ? ListBody(
                    children: [
                      Text('time-step').tr(),
                      SizedBox(
                        height: 5.0,
                      ),
                      DropdownButton(
                        value: timeStep,
                        onChanged: (value) {
                          setState(() {
                            timeStep = value;
                          });
                        },
                        items: [
                          DropdownMenuItem(
                            value: '30',
                            child: Text('30'),
                          ),
                          DropdownMenuItem(
                            value: '60',
                            child: Text('60'),
                          ),
                        ],
                      )
                    ],
                  )
                : ListBody(
                    children: [
                      Text('time-step').tr(),
                      SizedBox(
                        height: 5.0,
                      ),
                      CupertinoSegmentedControl(
                        groupValue: timeStep,
                        children: {
                          '30': Text('30'),
                          '60': Text('60'),
                        },
                        onValueChanged: (value) {
                          setState(() {
                            timeStep = value;
                          });
                        },
                      ),
                    ],
                  ),
          ],
        ),
      ),
    );
  }
}

标签: flutterdartbloc

解决方案


原因是你close(kill)BLoC这里

       BlocProvider.of<ManualInputBloc>(context).close();

将侦听器更改为

       listener: (context, state) {
              if (state is ManualInputError) {
                Platform.isAndroid
                    ? CustomAlertDialog.showAndroidAlertDialog(
                        context,
                        state.alertDialogErrorTitle,
                        state.alertDialogErrorContent)
                    : CustomAlertDialog.showIosAlertDialog(
                        context,
                        state.alertDialogErrorTitle,
                        state.alertDialogErrorContent);
              }
            },

推荐阅读