如何在Flutter中显示来自Stream的Snackbar?

问题描述 投票:1回答:1

一旦SnackBarStream发送新的String,我想展示String

我试图在StreamBuilder中放置一个StatefulWidget,以便能够调用Scaffold.of()(因为它现在是另一个context)。但后来我收到这个错误:

抛出以下断言构建StreamBuilder(dirty,state:_StreamBuilderBaseState>#7f258):在构建期间调用setState()或markNeedsBuild()。此Scaffold窗口小部件无法标记为需要构建,因为框架已在构建窗口小部件的过程中。只有当其中一个祖先正在构建时,才能将窗口小部件标记为需要在构建阶段构建。允许此异常,因为框架在子项之前构建父窗口小部件,这意味着将始终构建脏后代。否则,在此构建阶段,框架可能不会访问此窗口小部件。调用setState()或markNeedsBuild()的小部件是:Scaffold(依赖项:[_ LocalocalScope- [GlobalKey#0e1f6],Directionality,_InheritedTheme,MediaQuery],状态:ScaffoldState#3f2aa(代码:跟踪2代码))小部件在进行违规调用时正在构建的是:StreamBuilder(dirty,state:_StreamBuilderBaseState>#7f258)

我怎么解决这个问题?

这是一个显示问题的简单代码段:

import 'dart:async';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TestHome(),
    );
  }
}

class TestHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamSnackbar(),
    );
  }
}

class StreamSnackbar extends StatefulWidget {
  @override
  _StreamSnackbarState createState() => _StreamSnackbarState();
}

class _StreamSnackbarState extends State<StreamSnackbar> {
  final status = StreamController<String>();

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                status.add('Test');
              },
              child: Text('Press me to trigger the Snackbar!'),
            ),
            StreamBuilder<String>(
              stream: status.stream,
              builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
                if (snapshot.hasData) {
                  Scaffold.of(context)
                      .showSnackBar(SnackBar(content: Text(snapshot.data)));
                }
                return Container(
                  height: 0,
                  width: 0,
                ); // just because we need to return a Widget
              },
            ),
          ],
        ),
      ),
    );
  }
}
flutter stream
1个回答
1
投票

没有必要使用StreamBuilder。无论如何,显示SnackBar必须在同步build()执行之外完成。

@override
void initState() {
  super.initState();
  status.stream.forEach((e) =>
    Scaffold.of(context)
        .showSnackBar(SnackBar(content: Text(e))));
}

@override
void dispose() {
  status.close();
  super.dispose();
}
© www.soinside.com 2019 - 2024. All rights reserved.