使用 RxJava 在时间跨度内捕获用户点击次数

Catch number of user clicks in timespan using RxJava

我有应用程序,其中隐藏了调试菜单。我需要启用这个秘密菜单,如果(Build.DEBUG 和)用户在一秒钟内点击视图例如 4 次。 我想用这个 RxJava。

我在 weddingpartyapp 上尝试了 Kaushik Gopal 的 DebouncedBuffer,但这会计算点击次数,如果在指定的时间段内没有点击,则值为 returns。

我已经通过使用简单的 buffer() 达到了预期的效果,但是如果没有点击,它会开始缓冲并不断发出空列表。我可以添加 filter(),但我想以不同的方式获得相同的结果。

我想在第一次点击后开始缓冲,并在提供的时间段(debounce()?)内收集所有点击(bufer()?),然后停止缓冲。我发现 buffer(bufferOpenings, bufferClosingSelector)

它满足我的需要,我在 Intro-To-RxJava 中找到了使用示例 但这取决于 interval()。如何更改,第一个可观察值将是组中的第一个值,并且函数将在第一个值一秒后触发?

此外,我发现,它增加了检查项目的数量(这也会有帮助,因为我可以在收到 4 次点击后停止 Observable),但是我可以达到同样的效果吗?创建新的 Operator?

您找到的 buffer 是一个好的开始,但您还需要 publish 将流分成两部分:一个将被缓冲以查看是否有 4 次点击,另一个将作为打开有时间限制的缓冲区的触发器:

PublishSubject<Integer> source = PublishSubject.create();
TestScheduler ts = Schedulers.test();

source.publish(p -> 
    p.buffer(p, o -> Observable.timer(1, TimeUnit.SECONDS, ts))
)
.filter(v -> v.size() == 4)
.subscribe(v -> System.out.println("Secret menu"));

System.out.println("Should open secret menu:");

source.onNext(1);
ts.advanceTimeBy(100, TimeUnit.MILLISECONDS);
source.onNext(1);
ts.advanceTimeBy(100, TimeUnit.MILLISECONDS);
source.onNext(1);
ts.advanceTimeBy(100, TimeUnit.MILLISECONDS);
source.onNext(1);
ts.advanceTimeBy(1000, TimeUnit.MILLISECONDS);


System.out.println("Should not open anything:");

source.onNext(1);
ts.advanceTimeBy(100, TimeUnit.MILLISECONDS);
source.onNext(1);
source.onNext(1);
ts.advanceTimeBy(1000, TimeUnit.MILLISECONDS);
source.onNext(1);

这是我发现的一种简单方法:

fun <T> Observable<T>.debounceWithEvents(time:Long,timeUnit: TimeUnit) = takeUntil(debounce(time, timeUnit))

它将 return 一个发出所有事件的可观察对象,直到第一个事件被去抖。 希望这会有所帮助:)