View flatter:bloc,如何显示警报对话框
我是新加入集团模式和流媒体的。我想在按下按钮时显示一个警报对话框,但我找不到方法。实际上,我的代码是:View flatter:bloc,如何显示警报对话框,view,stream,flutter,alert,View,Stream,Flutter,Alert,我是新加入集团模式和流媒体的。我想在按下按钮时显示一个警报对话框,但我找不到方法。实际上,我的代码是: Widget button() { return RaisedButton( child: Text('Show alert'), color: Colors.blue[700], textColor: Colors.white, onPressed: () { bloc.submit(); }); }
Widget button() {
return RaisedButton(
child: Text('Show alert'),
color: Colors.blue[700],
textColor: Colors.white,
onPressed: () {
bloc.submit();
});
}
return Scaffold(
appBar: AppBar(
title: Text("Title"),
),
body: StreamBuilder(
stream: bloc.getAlert,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text("I have Dataaaaaa ${snapshot.data}");
} else
return ListView(
children: <Widget>[
Container(
button()
)
...
我试着做一些类似的事情:
Widget button() {
return StreamBuilder(
stream: submissionStream
builder: (context, snapshot){
if (snapshot.hasData){
return showDialog(...)
}else
return RaisedButton(
child: Text('Show alert'),
color: Colors.blue[700],
textColor: Colors.white,
onPressed: () {
bloc.submit();
});
}
但是,当然,它不起作用。构建工作时不能显示对话框。当您有了新数据时,您就创建了一个新的小部件。在这种情况下,最好不要使用流,但如果有必要,应该使用流 WidgetsBinding.instance.addPostFrameCallback((\u)=>yourFunction(context)) 或 微任务(()=>showDialogFunction(上下文)) 在你的假设中
if(snapshot.hasData){
WidgetsBinding.instance.addPostFrameCallback((\u)=>showDialogFunction(上下文));
}
此代码将在生成方法之后启动,所以对话框将立即显示
Bloc函数总是返回widget,所以当流有数据时总是返回button()或不同的wiget,这就是我所做的,它可能是错误的,因为我也是一个新手。但对我的场景有效
Widget build(BuildContext context) {
final authBloc = BlocProvider.of<AuthBloc>(context);
authBloc.outServerResponse.listen((serverResponse) {
if (serverResponse.status == 'success') {
_navigateToLogin();
} else {
_showSnakBar(serverResponse.message);
}
});
.... Rest of the code which returns the widget,
which in my case is form widget with button for submitting as follows,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
authBloc.processRegister.add(_registrationData.toMap());
}
}
您可以使用显示对话框、快捷键或导航到新页面
使用这种方法,您可能希望重构以依赖于集团状态,而不是直接访问流
返回脚手架(
appBar:appBar(
标题:文本(“标题”),
),
正文:BlocProvider(
创建:()=>YourBloc(),
子:堆栈([
SnackbarManager(),
YourScreen(),
]),
),
);
...
///这基本上是一个空的UI小部件
///管理snackbar
类SnackbarManager扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回BlocListener(
侦听器:(上下文、状态){
if(state.hasMyData){
Scaffold.of(上下文).showSnackBar(SnackBar(
内容:
文本(“我得到了数据”),
));
}
},
子级:容器(),
);
}
}
这个过程对我来说很有效。
在返回小部件之前,我调用了我的对话框
微任务(()=>showloginssuccess(BuildContext)) 我知道我来晚了,但也许这会对某人有所帮助。 我目前正在学习BLoC,遇到了类似的问题 首先,我想推荐一种新的。 它包含一些小部件,可以帮助您实现这一点,如
BlocListener
和BlocConsumer
如果不想使用它,可以尝试使用StatefulWidget
和分别对其进行侦听,并使用逻辑显示对话框。(还要确保您的流正在广播,如我的示例所示,这样它就可以有多个侦听器)
我举了一个例子,你可以把过去复制到:
导入'dart:async';
进口“包装:颤振/材料.省道”;
final myStream=StreamController.broadcast();
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主题:ThemeData.dark(),
debugShowCheckedModeBanner:false,
家:脚手架(
正文:中(
子项:MyWidget(),
),
),
);
}
}
类MyWidget扩展了StatefulWidget{
@凌驾
_MyWidgetState createState()=>\u MyWidgetState();
}
类_MyWidgetState扩展状态{
initState(){
super.initState();
myStream.stream.listen((显示){
如果(显示)
显示对话框(
禁止:错误,
上下文:上下文,
生成器:(上下文){
返回警报对话框(
标题:文本(“MyDialog”),
行动:[
文本按钮(
子项:文本('Close'),
已按下:(){
myStream.sink.add(false);
}),
]
);
}
);
如果(!show){
Navigator.pop(上下文);
}
});
}
@凌驾
小部件构建(构建上下文){
返回中心(子项:提升按钮(
子项:文本(“显示警报”),
已按下:(){
myStream.sink.add(true);
}));
}
}
我通过维护两个上下文解决了这个问题,如下所示
**
A类型的BlocProvider==>B类小部件(showdialog)(上下文:上下文,生成器(context2){
Blocprovider.value(值:Blocprovider.of.context)
孩子:布洛克斯腾纳(
listner(上下文2,州)
{//
你的作品
//}
子:AlertDialog(一些小部件
按钮函数()=>context.read()。函数或属性名
//
1.这里我们称之为旧上下文,事实上它已向提供者注册,2.上下文2仅用于构建新的构建器小部件。
3.因此,我们让bloc通过一个导航并在导航警报小部件中访问,而无需创建它是的,在这些情况下避免使用bloc可能更好,但由于我对它相当陌生,我仍然需要学习如何正确地使用它。不过,您建议的方法很有效,所以谢谢您!似乎适用于每个构建流将使用“authBloc.outServerResponse.listen”一次又一次地订阅。我认为订阅必须关闭。@RideSun true。如果它是有状态的,最好将其置于initstate中&close on dispose。我正试图使用bloc在对话框中显示未来的数据,我不明白您使用stack[SnackBarManager(),screen()]时的意思在这种情况下,堆栈是否允许screen和blockListener同时运行?
Widget build(BuildContext context) {
final authBloc = BlocProvider.of<AuthBloc>(context);
authBloc.outServerResponse.listen((serverResponse) {
if (serverResponse.status == 'success') {
_navigateToLogin();
} else {
_showSnakBar(serverResponse.message);
}
});
.... Rest of the code which returns the widget,
which in my case is form widget with button for submitting as follows,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
authBloc.processRegister.add(_registrationData.toMap());
}
}
_navigateToLogin() {
Navigator.of(context).pop();
}
_showSnakBar(String msg) {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text(msg),
),
);
}
import 'dart:async';
import 'package:flutter/material.dart';
final myStream = StreamController<bool>.broadcast();
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
initState() {
super.initState();
myStream.stream.listen((show){
if(show)
showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return AlertDialog(
title: Text('MyDialog'),
actions: [
TextButton(
child: Text('Close'),
onPressed: (){
myStream.sink.add(false);
}),
]
);
}
);
if(!show) {
Navigator.pop(context);
}
});
}
@override
Widget build(BuildContext context) {
return Center(child: ElevatedButton(
child: Text('Show Alert'),
onPressed: (){
myStream.sink.add(true);
}));
}
}
BlocProvider of type A ==>widget class B(showdialog(context:context,builder(context2){
Blocprvider.value(value:Blocprovider.of<A>.context)
child:BlocListener(
listner(context2,state)
{//
your works
//}
child:AlertDialog( some widgets
a button function ()=> context.read<A>().function or property name
//