为什么此“ StreamBuilder”使用以前关闭的流中的数据?

时间:2019-12-08 11:58:57

标签: flutter dart

我有一个非常简单的Flutter应用程序:

import 'package:flutter/material.dart';
import 'dart:async';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Debug",
      initialRoute: "/",
      routes: {
        "/": (context) => MainPage(),
      },
    );
  }
}

MainPage为:

class MainPage extends StatelessWidget {
  final _rebuilder = StreamController<void>.broadcast();

  @override
  Widget build(BuildContext context) {
    debugPrint("Initializing the app main page");
    var isButtonPressed = StreamController<bool>.broadcast();

    return StreamBuilder<void>(
      stream: _rebuilder.stream,
      builder: (context, snapshot) {
        debugPrint("Rebuilding (stream = ${isButtonPressed.stream.hashCode})");
        return StreamBuilder<bool>(
          stream: isButtonPressed.stream,
          initialData: false,
          builder: (context, snapshot) {
            var pressed = snapshot.data;
            debugPrint("Button state: $pressed (stream = ${isButtonPressed.stream.hashCode})");
            return RaisedButton(
              onPressed: () {
                debugPrint("Closing and rebuilding (stream = ${isButtonPressed.stream.hashCode})");
                isButtonPressed.sink.add(true);
                isButtonPressed.close();
                isButtonPressed = StreamController<bool>.broadcast();
                _rebuilder.sink.add(null);
              },
              child: Text("Pressed: $pressed"),
            );
          },
        );
      },
    );
  }
}

它使用两个StreamController_rebuilder用于生成新按钮,而isButtonPressed用于更新现有按钮

如您所见,当按下按钮时,我会通过流的接收器对其进行更新,然后关闭流,最后要求创建一个新按钮。

但是,看起来好像是第二次创建按钮的StreamBuilder时,由于initialData: false尽管pressed == true不同,所以并未使用stream.hashCode对其进行初始化。 / p>

I/flutter ( 4207): Initializing the app main page
I/flutter ( 4207): Rebuilding (stream = 773570673)
I/flutter ( 4207): Button state: false (stream = 773570673)
I/flutter ( 4207): Closing and rebuilding (stream = 773570673)
I/flutter ( 4207): Rebuilding (stream = 786124862)
I/flutter ( 4207): Button state: true (stream = 786124862)

我不明白。我希望新流为空,因此按钮的状态为false。为什么不这样?

1 个答案:

答案 0 :(得分:1)

问题不在Streams中。 Streambuilder本身也使用状态方法的小部件。因此,您应该将键属性添加到Streambuilder就是这样。下面的代码。

class MainPage extends StatelessWidget {
  final _rebuilder = StreamController<void>.broadcast();

  @override
  Widget build(BuildContext context) {
    debugPrint("Initializing the app main page");
    var isButtonPressed = StreamController<bool>.broadcast();

    return StreamBuilder<void>(
      stream: _rebuilder.stream,
      builder: (context, snapshot) {
        debugPrint("Rebuilding (stream = ${isButtonPressed.stream.hashCode})");
        return StreamBuilder<bool>(
          key: UniqueKey(),
          stream: isButtonPressed.stream,
          initialData: false,
          builder: (context, snapshot) {
            var pressed = snapshot.data;
            debugPrint(
                "Button state: $pressed (stream = ${isButtonPressed.stream.hashCode})");
            return RaisedButton(
              onPressed: () {
                debugPrint(
                    "Closing and rebuilding (stream = ${isButtonPressed.stream.hashCode})");
                isButtonPressed.sink.add(true);
                isButtonPressed.close();
                isButtonPressed = StreamController<bool>.broadcast();
                _rebuilder.sink.add(null);
              },
              child: Text("Pressed: $pressed"),
            );
          },
        );
      },
    );
  }
}

(感谢@Delgan发现逻辑错误,答案已编辑。)