如何在 Dart 的流构建器中切换我正在收听的流?

Posted

技术标签:

【中文标题】如何在 Dart 的流构建器中切换我正在收听的流?【英文标题】:How can i switch the stream I am listening to in a streambuilder in Dart? 【发布时间】:2020-01-16 09:28:04 【问题描述】:

基本上,当页面首次加载时,我想使用 1 个通过地理位置查询但检查变量 socialVisible 为 true 的文档的流,然后当用户单击按钮进行切换时,我希望流仍然通过查询地理位置,但现在使用字段 profVisible 检查文档。

理论上这很简单,每当按下相应的按钮时,我都会设置状态,以便 socialPressed=true 和 profPressed=false,然后在流构建器中,我使用三元运算符根据真值决定应该使用哪个流socialPressed 和 profPressed。

但是,这仅适用于第一次单击,socialPressed 的初始值为 true,因此初始流是社交流,然后当我单击转到教授时,它会成功切换流。但是,在这段时间之后,当我尝试返回社交时,教授的所有文件仍然存在而不是被社交所取代?即使我将初始流切换到 prof 也会发生这种情况,但我不明白为什么会这样?

StreamBuilder(
            stream:socialPressed==true?socStream:proStream,
            builder:
                (context, AsyncSnapshot<List<DocumentSnapshot>> snapshots) 
              if (!snapshots.hasData) 
                return Container(
                    alignment: FractionalOffset.center,
                    child: CircularProgressIndicator());
               else 
               return Container(
                    child: Container(
                      child: (snapshots.data.length == 0)
                          Container(
                        height: MediaQuery.of(context).size.height * 2 / 3,
                        child: ListView.builder(
                          itemBuilder: (context, index) 
                            DocumentSnapshot doc = snapshots.data[index];
                          return UserTile('this is where i use the doc data'),
                          itemCount: snapshots.data.length,
                        ),),));,)

这是我代码的基本结构,我已经删除了不相关的信息。

编辑: 请求按钮回调代码:

 FloatingActionButton(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(Radius.circular(16.0))),
                onPressed: () 
                  setState(() 
                    likeType='social';
                    socialPressed=!socialPressed;
                  );
                ,
                elevation: 0,
                heroTag: 'socialButton',
                backgroundColor: socialPressed==false?Colors.grey[100]:Color(0xFFe0bdff),
                child: Icon(
                  Entypo.drink,
                  color: Color(0xFF8803fc),
                ),
              ),
              FloatingActionButton(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(Radius.circular(16.0))),
                onPressed: () 
                  setState(() 
                    likeType='prof';
                    socialPressed=!socialPressed;
                  );
                ,
                elevation: 0,
                heroTag: 'profButton',
                backgroundColor: socialPressed==true?Colors.grey[100]:Color(0xFFb9ebe9),
                child: Row(
                  children: <Widget>[
                    SizedBox(
                      width: MediaQuery.of(context).size.width / 30,
                    ),
                    Icon(
                      FontAwesome.graduation_cap,
                      color: Color(0xFF096664),
                    ),
                  ],

                ),
              ),

【问题讨论】:

使用来自Observable的*Map()方法之一(我将从switchMap()开始) 你能提供一些示例或伪代码吗?我不确定我将如何实现这个 pub.dev/documentation/rxdart/latest/rx/Observable/… 我已经使用了,它适用于这种情况仍然有另一个错误,但如果你为 switchmap 添加答案,我会接受答案已解决 【参考方案1】:

我也遇到过这个问题。我正在使用 RX Dart 并尝试根据布尔变量切换流。

我最初将 PublishSubject 用于我的流。切换到行为主题为我解决了这个问题。目前我还没有足够的知识知道为什么会这样,但会尝试进一步探索并尽可能在此处进行编辑。

之前的代码:

final _activeOrdersFetcher = PublishSubject<OrderListModel>();
final _completedOrdersFetcher = PublishSubject<OrderListModel>();

StreamBuilder<OrderListModel>(
      stream: isActive
          ? _ordersBloc.getActiveOrders
          : _ordersBloc.getCompletedOrders

新代码更改:

final _activeOrdersFetcher = BehaviorSubject<OrderListModel>();
final _completedOrdersFetcher = BehaviorSubject<OrderListModel>();

【讨论】:

【参考方案2】:

您使用什么逻辑来设置状态?看起来您正在使用两个变量,socialPressedprofPressed。如果你只有两种状态,我会考虑只使用一个变量。

没有您的代码,我们只能推测出了什么问题。但这应该在按钮的 onPressed 回调中起作用:

onPressed: () => setState(()  socialPressed = !socialPressed; )

【讨论】:

是的,我最初使用两个变量,但是是的,我最初认为设置变量真值的逻辑导致了这种情况,但事实并非如此。我什至创建了两个流构建器,并根据 socialPressed 和 profPressed 的真值使用相应的一个。发生的事情是当我单击 prof 按钮时,streambuilder 代码块中的 print 语句执行,反之亦然,但流没有改变。我不知道是否有关于更改流的规则我需要停止收听流吗?我只尝试了 1 个变量,没有工作 如果您可以编辑您的问题以包含您的 onPressed 回调会有所帮助 好的,我添加了代码并添加了您的推荐,但我再次测试该程序使用变量输入了正确的代码块,但未能使用正确的流。

以上是关于如何在 Dart 的流构建器中切换我正在收听的流?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Dart 中提供 Future<String> 来流式传输需要 String 的流? [复制]

在 Flutter 的流构建器中使用 Future 构建器是正确的

如何使用来自inheritedWidget 的流处理导航?

协程中的流

协程中的流

协程中的流