【问题标题】:Flutter - StreamBuilder Error "Bad State:Stream has already be listened to"Flutter - StreamBuilder 错误“状态不佳:Stream 已被收听”
【发布时间】:2021-02-15 22:47:57
【问题描述】:

我在 Stateful Widget 中使用了一个切换开关按钮,它设置了一些布尔变量状态是 Builder 是有条件地呈现还是 StreamBuilder

 Expanded(
    child: Padding(
                      padding:
                          const EdgeInsets.fromLTRB(10.0, 32.0, 10.0, 70.0),
                      child: (showPrivate == true && showPublic == false)
                          ? Builder(
                              key: Key("private"),
                              builder: (context) {
                                if (products.length != 0 &&
                                    products.length != null)
                                  return ListView.builder(
                                    scrollDirection: Axis.vertical,
                                    itemCount: products.length,
                                    itemBuilder: (context, i) {
                                      // ListProduct gets product from map
                                      String key = products.keys.elementAt(i);
    
                                      if (products[key].isAmount != "0")
                                        return ListProduct(
                                            products[key], false);
                                      else
                                        return SizedBox();
                                    },
                                  );
                                else
                                  return Center(
                                    child: Text("Empty!"),
                                  );
                              })
                          : (showPrivate == false && showPublic == true)
                              ? Expanded(
                                  child: StreamBuilder(
                                    stream: streamSocket.getResponse,
                                    builder: (context,
                                        AsyncSnapshot<String> snapshot) {
                                      if (snapshot.data != null) {
                                        return Container(
                                          child: Text(snapshot.data),
                                        );
                                      } else {
                                        return ListView.builder(
                                          scrollDirection: Axis.vertical,
                                          itemCount: products.length,
                                          itemBuilder: (context, i) {
                                            // ListProduct gets product from map
                                            String key =
                                                products.keys.elementAt(i);
    
                                            if (products[key].isAmount != "0")
                                              return ListProduct(
                                                  products[key], false);
                                            else
                                              return SizedBox();
                                          },
                                        );
                                      }
                                    },
                                  ),
                                )
                              : Text("")),)

我已经构建了这个自定义的流套接字控制器

class StreamSocket {
  var _socketResponse = StreamController<String>();

  void Function(String) get addResponse => _socketResponse.sink.add;
  Stream<String> get getResponse => _socketResponse.stream;

  void connectToWebSocket() async {
    try {
      IO.Socket socket = IO.io(
          "http://localhost:3001/",
          IO.OptionBuilder()
              .setTransports(['websocket'])
              .disableAutoConnect()
              .build());

      socket.connect();

    } catch (err) {
      print("Error: $err");
    }
  }

  void dispose() {
    _socketResponse.close();
  }
}

当我切换 StreamBuilder 超过 2 次并输出此错误时发生错误:

Bad state: Stream has already been listened to.
The relevant error-causing widget was
Expanded

【问题讨论】:

  • 你在你的widget的dispose中调用StreamSocket dispose()方法吗?
  • @DNS 不,我没有对流的处置。每次切换开关时都应该丢弃它吗?
  • 不,您应该在小部件处置方法中处置它。你确定在 initState 中初始化你的流并不能解决它吗?它对我有用

标签: flutter dart socket.io


【解决方案1】:

您需要在您的小部件中定义一个流,在 initState 中将其分配给 StreamSocket 流并在 StreamBuilder 中使用它

代码如下:

StreamSocket streamSocket;
Stream<String> stream;

@override
  void initState() {
    streamSocket = StreamSocket();
    stream = streamSocket.getResponse;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
     return  Expanded(
    child: Padding(
                      padding:
                          const EdgeInsets.fromLTRB(10.0, 32.0, 10.0, 70.0),
                      child: (showPrivate == true && showPublic == false)
                          ? Builder(
                              key: Key("private"),
                              builder: (context) {
                                if (products.length != 0 &&
                                    products.length != null)
                                  return ListView.builder(
                                    scrollDirection: Axis.vertical,
                                    itemCount: products.length,
                                    itemBuilder: (context, i) {
                                      // ListProduct gets product from map
                                      String key = products.keys.elementAt(i);
    
                                      if (products[key].isAmount != "0")
                                        return ListProduct(
                                            products[key], false);
                                      else
                                        return SizedBox();
                                    },
                                  );
                                else
                                  return Center(
                                    child: Text("Empty!"),
                                  );
                              })
                          : (showPrivate == false && showPublic == true)
                              ? Expanded(
                                  child: StreamBuilder(
                                    stream: stream,
                                    builder: (context,
                                        AsyncSnapshot<String> snapshot) {
                                      if (snapshot.data != null) {
                                        return Container(
                                          child: Text(snapshot.data),
                                        );
                                      } else {
                                        return ListView.builder(
                                          scrollDirection: Axis.vertical,
                                          itemCount: products.length,
                                          itemBuilder: (context, i) {
                                            // ListProduct gets product from map
                                            String key =
                                                products.keys.elementAt(i);
    
                                            if (products[key].isAmount != "0")
                                              return ListProduct(
                                                  products[key], false);
                                            else
                                              return SizedBox();
                                          },
                                        );
                                      }
                                    },
                                  ),
                                )
                              : Text("")),);
   }

【讨论】:

  • 非常感谢!不幸的是,我遇到了同样的错误:/ 当我通过切换开关切换到 streambuilder 超过 2 次时,它返回错误“Bad State: Stream has been listened”。
猜你喜欢
  • 2021-07-04
  • 2021-03-06
  • 2018-09-01
  • 1970-01-01
  • 2021-02-03
  • 2023-03-29
  • 2021-12-26
  • 1970-01-01
  • 2023-02-16
相关资源
最近更新 更多