18

Flutter では、ストリームの値が変更されたときに Navigator.push を呼び出すにはどうすればよいですか? 以下のコードを試しましたが、エラーが発生します。

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("");
        });

ここに画像の説明を入力

4

2 に答える 2

33

StreamBuilderナビゲーションの処理に は使用しないでください。StreamBuilder画面のコンテンツを構築するために使用され、それ以外には何も使用されません。

代わりに、ストリームをリッスンして副作用を手動でトリガーする必要があります。これは、a を使用して/StatefulWidgetをオーバーライドすることによって行われます。initStatedispose

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ストリーム (通常は BLoC) を取得するために を使用している場合は、 /didChangeDependenciesの代わりに使用する必要があることに注意してください。initStatedidUpdateWidget

これはにつながります:

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();
  }
}
于 2019-01-09T12:16:14.493 に答える