【问题标题】:How to convert a stream before it reaches StreamBuilder?如何在流到达 StreamBuilder 之前对其进行转换?
【发布时间】:2021-02-04 19:40:06
【问题描述】:

我想在流到达 StreamBuilder 之前对其进行转换,但不知道会是什么样子。作为测试,我在下面创建了简单的倒计时。我想做的是将 CountDownConversion 提供给 StreamBuilder,但如果我取消注释它,我会收到编译错误。我一直在阅读有关流和 StreamBuilder 的信息,但在 StreamBuilder 之前还没有看到任何人进行过这种类型的转换。如果有人能提示我,我将不胜感激。

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

Stream<int> countDown() async* {
    int i = 42;
    while (true) {
      await Future.delayed(Duration(seconds: 1));
      yield i--;
      if (i == 0) break;
    }
  }

// Stream<String> countDownConverter() {
//   final number = countDown();
//   return number.toString();
// }

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
    stream: countDown(), // <- want countDownConverter() here
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.active) {
        final String count = snapshot.data.toString();
        return Text(count, style: Theme.of(context).textTheme.headline4);
      } else return Text('Working...');
    });
  }
}

【问题讨论】:

  • 使用Stream.map方法,比如var mapped = countDown().map((i) =&gt; i.toString());现在可以使用stream: mapped
  • 谢谢@pskink。我的实际用例是将 json 从 Firestore 转换为我的本地模型。我想在我的 ViewModel 中进行转换,而不是在 Flutter View 代码中使用 json,如果这有意义的话
  • 这就是为什么我写了var mapped = countDown().map((i) =&gt; i.toString()); 而不是stream: countDown().map((i) =&gt; i.toString()), - 只需调用map 方法来获取你的firestore Stream(块,提供者等) - 换句话说:映射你的firestore Stream 变成另一个 Stream
  • 啊。完美的。谢谢!

标签: flutter dart stream-builder


【解决方案1】:

也将countDownConverter 转换为异步生成器,并使用await for 让它监听countDown

Stream<String> countDownConverter() async* {
  await for (int n in countDown()) {
    yield n.toString();
  }
}

虽然理想情况下,您可以简单地在流本身上使用map,而不是编写转换方法:

StreamBuilder(
  stream: countDown().map((i) => i.toString()),
  ...
),

【讨论】:

  • 谢谢@Abion47。那很完美。当您说理想使用map 时,是因为它的击键次数更少还是有其他优势?
  • @buttonsrtoys 这是理想的,因为当有一个预构建的函数可以满足您的目的时,不要重新发明轮子。
猜你喜欢
  • 2013-04-20
  • 2022-07-11
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
  • 2020-06-23
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多