使用 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 一个发出所有事件的可观察对象,直到第一个事件被去抖。
希望这会有所帮助:)
我有应用程序,其中隐藏了调试菜单。我需要启用这个秘密菜单,如果(Build.DEBUG
和)用户在一秒钟内点击视图例如 4 次。
我想用这个 RxJava。
我在 weddingpartyapp 上尝试了 Kaushik Gopal 的 DebouncedBuffer,但这会计算点击次数,如果在指定的时间段内没有点击,则值为 returns。
我已经通过使用简单的 buffer()
达到了预期的效果,但是如果没有点击,它会开始缓冲并不断发出空列表。我可以添加 filter()
,但我想以不同的方式获得相同的结果。
我想在第一次点击后开始缓冲,并在提供的时间段(debounce()
?)内收集所有点击(bufer()
?),然后停止缓冲。我发现 buffer(bufferOpenings, bufferClosingSelector)
它满足我的需要,我在 Intro-To-RxJava 中找到了使用示例
但这取决于 interval()
。如何更改,第一个可观察值将是组中的第一个值,并且函数将在第一个值一秒后触发?
此外,我发现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 一个发出所有事件的可观察对象,直到第一个事件被去抖。 希望这会有所帮助:)