Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
View flatter:bloc,如何显示警报对话框_View_Stream_Flutter_Alert - Fatal编程技术网

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
//