在StringBuilder中加载多个流,一个流接一个流。

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

我是一个新的Dart Streams,并有一个困难的时间弄清楚这一点。

基本上,我有一个流用于文件下载,然后另一个流用于文件处理。文件下载流只能在文件处理流之后初始化,因为它取决于下载的文件。

我需要显示一个进度部件,从0到100%,然后再从0到100%。

我试着用rxDart concatWith来合并流,但没有用。ConnectionState.done是在第一个流上调用的,它没有监听另一个流。我也不知道这样做是否正确。

如果我试图在构建器中设置新的流,我会得到这个错误。

setState()或markNeedsBuild()在构建过程中被调用。

builder: (context, snapshot) {
      print(snapshot.connectionState);

      if (snapshot.connectionState == ConnectionState.done) {
        setState(() {
          stream =
              Stream.periodic(Duration(seconds: 1), (i) => _source2[i]).take(_source2.length); // New Stream
        });
      }

有什么好的方法可以做到这一点?

flutter dart
1个回答
0
投票

我能够解决我的问题,通过添加

WidgetsBinding.instance.addPostFrameCallback((_){

在构建器中。

下面是一个简单的例子,它可以一个接一个地输出两个流。

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

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

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  var stream; // state variable

  List<String> _source = ['a', 'b', 'c', 'd', 'e', 'f'];
  List<String> _source2 = ['g', 'h', 'i'];

  var _count = 0;

  @override
  void initState() {
    super.initState();
    // stream = newStream(); // initial stream

    stream = Stream.periodic(Duration(seconds: 1), (i) => _source[i]).take(_source.length);
  }

  @override
  Widget build(BuildContext context) {
    var streamBuilder = StreamBuilder(
        initialData: "0",
        stream: stream,
        builder: (context, snapshot) {
          print(snapshot.connectionState);

          if (snapshot.connectionState == ConnectionState.done) {
            _count++;
            if (_count < 2) {
              WidgetsBinding.instance.addPostFrameCallback((_) {
                setState(() {
                  stream = Stream.periodic(Duration(seconds: 1), (i) => _source2[i])
                      .take(_source2.length);
                });
              });
            }
          }

          if (snapshot.hasData) {
            print(snapshot.data);
            return new Text(snapshot.data);
          } else {
            return new Text('no data');
          }
        });
    return MaterialApp(
        title: 'Trial',
        home: Scaffold(
            appBar: AppBar(title: Text('Stream builder')),
            body: Column(
              children: <Widget>[
                streamBuilder,
              ],
            )));
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.