flutter - 如何在 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;
});
},
),
],
),
],
),
),
);
}
}
解决方案
原因是你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);
}
},
推荐阅读
- c# - 无法滚动添加到面板中的 userControl
- spring - Spring MVC 和 LocalDateTime java 8
- c++ - 有没有办法强制忽略 MacOS 上的重复符号?
- sql-server - 从 Cloud Snowflake Server 更新本地 Sql Server 数据库获取新数据的最快方法
- python - django 表单发布请求在 __init__ 方法上引发错误
- gtk - gnome.gtk-doc() 在 Yocto (do_install) 中给出权限被拒绝错误
- jquery - 日历验证错误仅在第二次通过 Jquery UI 选择日期后才消失
- java - Obj obj =new Obj(); 有什么区别?和对象 obj;
- c# - 发布 Azure 函数返回“发布遇到错误”路径 \bin 不存在
- python - 在 LAN 上使用套接字会引入任何安全问题吗?