在Flot中,当流的值发生变化时,我如何调用Navigator.ush呢?我已经try 了下面的代码,但出现错误.

StreamBuilder(
        stream: bloc.streamValue,
        builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
          if (snapshot.hasData && snapshot.data == 1) {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SomeNewScreen()),
            );
          }

          return Text("");
        });

enter image description here

推荐答案

您不应该使用StreamBuilder来处理导航. StreamBuilder用于构建屏幕的内容,而不是其他内容.

相反,你将不得不听流来手动触发副作用.这是通过使用StatefulWidget和覆盖initState/dispose来实现的:

class Example extends StatefulWidget {
  final Stream<int> stream;

  const Example({Key key, this.stream}) : super(key: key);

  @override
  ExampleState createState() => ExampleState();
}

class ExampleState extends State<Example> {
  StreamSubscription _streamSubscription;

  @override
  void initState() {
    super.initState();
    _listen();
  }

  @override
  void didUpdateWidget(Example oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.stream != widget.stream) {
      _streamSubscription.cancel();
      _listen();
    }
  }

  void _listen() {
    _streamSubscription = widget.stream.listen((value) {
      Navigator.pushNamed(context, '/someRoute/$value');
    });
  }

  @override
  void dispose() {
    _streamSubscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

请注意,如果您使用InheritedWidget来获取流(通常是阻塞),那么您将希望使用didChangeDependencies而不是initState/didUpdateWidget.

这导致:

class Example extends StatefulWidget {
  @override
  ExampleState createState() => ExampleState();
}

class ExampleState extends State<Example> {
  StreamSubscription _streamSubscription;
  Stream _previousStream;

  void _listen(Stream<int> stream) {
    _streamSubscription = stream.listen((value) {
      Navigator.pushNamed(context, '/someRoute/$value');
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final bloc = MyBloc.of(context);
    if (bloc.stream != _previousStream) {
      _streamSubscription?.cancel();
      _previousStream = bloc.stream;
      _listen(bloc.stream);
    }
  }

  @override
  void dispose() {
    _streamSubscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

Flutter相关问答推荐

ShaderMask上的文本渐变问题

material 3芯片,不能go 除输入芯片小部件上的轮廓

Flutter Riverpod,将默认的BTC值改写为我的新状态

Flutter Android Google Sign-in error:ApiException:10在确认软件包名称、SHA-1 fingerprint 和设置同意页面后出现异常

Flutter:无法构建iOS应用程序-找不到PigeonParser.h文件

Riverpod 2.0-如何使用FutureOr和AutoDisposeSyncNotificationer处理api状态代码?

Supabase Auth:重定向到 Google.com 而不是我的应用程序

在带有 flutter 的 Native Android 中,EventChannel.EventSink 始终为 null

参数类型void Function()无法分配给参数类型void Function(LongPressEndDetails)?

Flutter:注册 UI 出现 UI 问题(将注册框提升到顶部并向电话号码 pin 码添加一个框)

如果有空间则居中CustomScrollView

在允许屏幕 Select 和点击的同时保持通用对话框显示

如何在Flutter中显示ListView Builder区域外的列表数据?

如何解决需要一个标识符,但得到的是:.try 在:之前插入一个标识符.dart 错误

如何在 Flutter 中的 BackdropFilter.blur 中制作一个 100x100 的清晰孔

如何让小部件根据小部件的大小构建不同的布局?

使用 Riverpod 和 copyWith 方法更新数据类中列表中变量的值

Flutter sliver 持久化

Flutter HLS .m3u8 视频无法实时播放

Flutter 小部件中的视图和逻辑分离