当前位置: 首页 > 知识库问答 >
问题:

rxjava interval()某个事件后的重置时间

班言
2023-03-14

我正在用RxJava做一个Android应用程序,在其中一个页面上,我有一个按钮,当按下时,页面会做一个刷新。而且我还希望每10秒自动刷新一次,如果用户在此期间没有按下按钮。但是当用户点击按钮时,我希望自动刷新动作发生在点击后10秒钟。而不是继续自己的10秒间隔。例如,在第0秒,应用程序做一个自动刷新,然后在第3秒,用户按下按钮。然后自动刷新应该发生在第13秒,第23秒,等等。我知道有一个interval()运算符以一定的间隔发出项。但似乎没有办法“重置”开始时间。它有点像取消订阅和订阅interval()可以再次观察到。一段代码就像

Observable<Long> intervalObservable = Observable.inteval(10, TimeUnit.SECONDS)
RxView.click(refreshButton).map(ignored -> 0L)
      .merge(intervalObservable)
      .subscibe(ignore -> performRefresh());

如果有一种方法可以“取消合并”intervalobservable,那么我可以在下一个中取消合并,然后再次合并。但似乎没有。我怎样才能做到这一点?

共有1个答案

汪文光
2023-03-14

使用switchmap运算符可以很好地完成这一任务。每次按下按钮时,它将切换到可观察间隔的新订阅--这意味着它将重新开始。上一个订阅将自动删除,因此不会有多个间隔运行。

Observable<Long> intervalObservable = Observable.interval(10, TimeUnit.SECONDS);

RxView.clicks(refreshButton)
    .switchMap(ignored -> {
        return intervalObservable
            .startWith(0L)                 // For an immediate refresh
            .observeOn(AndroidSchedulers.mainThread())
            .doOnNext(x -> performRefresh());
    })      
    .subscribe();

StartWith向间隔添加一个即时值(单击按钮时立即导致刷新),而ObserveOn确保刷新发生在主线程上(这很重要,因为间隔将在后台线程上发出)。

更新:vman注意到,这个实现只有在用户第一次单击按钮后才开始刷新。下面的替代方案将在订阅时立即刷新,然后每10秒刷新一次,直到单击按钮--此时它将再次立即刷新,然后每10秒继续更新一次。

Observable<Long> intervalObservable = Observable.interval(10, TimeUnit.SECONDS)
    .startWith(0L)  // For an immediate refresh
    .observeOn(AndroidSchedulers.mainThread())
    .doOnNext(x -> performRefresh());

Observable<Long> buttonClickedObservable = RxView.clicks(refreshButton)
    .map(e -> 0L)  // To make the compiler happy
    .switchMap(ignored -> Observable.error(new RuntimeException("button pressed")));

Observable.merge(intervalObservable, buttonClickedObservable)
    .retry()
    .subscribe();
 类似资料:
  • 在 imi 中,使用模型关联时,提供了监听前置和后置事件的方法,让开发者可以更加灵活地做一些自定义处理。 事件 插入事件 前置事件名: IMI.MODEL.RELATION.INSERT.模型类名.模型属性名.BEFORE 后置事件名: IMI.MODEL.RELATION.INSERT.模型类名.模型属性名.AFTER 事件参数: 参数名 类型 描述 model string 模型类名 prop

  • 我正在尝试在我的应用程序中实现一个抽屉布局。我遵循android开发者网站上的教程,一切顺利。我只有一个“小”问题:我用午餐打开应用程序,打开抽屉布局,然后点击列表视图中的一个元素,一切都很顺利,但当我尝试打开另一个抽屉并点击他的一个元素时,我注意到我第一次点击的元素仍然被点击,而我无法点击其他任何元素。我的代码是:public class Eventi extends Activity{priv

  • 本文向大家介绍WinForm实现移除控件某个事件的方法,包括了WinForm实现移除控件某个事件的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了WinForm实现移除控件某个事件的方法,供大家参考借鉴一下。具体功能代码如下: 主要功能部分代码如下: 使用代码:

  • 问题内容: 是否有一个跟踪用户某些事件的表。 总是有一个动作,之后可能会有一个动作。 现在,我想查询这两个动作之间的时间差,以获取用户和之间的time_diff 。 现在,您可以假定没有多个条目(例如,至少一个,最大另一个)。 我想要这样的结果: 问题答案: 您可以使用以下查询: 该子句过滤掉仅包含一个动作的组,例如OP中的with记录。 演示在这里

  • 我有一个状态机,有三种可能的状态:状态1,状态2,状态3。 每当一个对象进入状态_3时,我想触发一个事件event1。 在我state_machine,我有 但只要状态从state1更改为state3或从state2更改为state3,就会正确触发事件。但当状态从state3转换到state3时,不会触发event1。我怎样才能做到这一点? 我知道从3号州到3号州不是一个州的过渡。我可以使用类似于

  • 那么我如何能够重置配置或者刷新log4j2配置运行时呢?