转载

使用throttleFirst解决按钮多次响应的问题

0. 前言

本文是Real World RxJava系列的第一篇,这个系列主要介绍如何使用RxJava解决Android开发中的一些实际问题。如果你还不了解RxJava的基本概念(Observable, Subscriber, Subscription等),建议先阅读RxJava初探。

1. 问题描述

我们首先实现一个Android中最常见的点击按钮,弹出一个新的Fragment的效果,其代码如下。

findViewById(R.id.normal_button).setOnClickListener(view -> {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction
.setCustomAnimations(R.animator.slide_up, R.animator.slide_down, R.animator.slide_up, R.animator.slide_down)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

transaction
.add(android.R.id.content, new DummyFragment())
.addToBackStack(DummyFragment.class.getSimpleName()).commit();
});

这段代码存在的问题在于当用户无意中多次点击到按钮时,会弹出多个Fragment,如图所示。

使用throttleFirst解决按钮多次响应的问题

2. 解决方案

我们通过使用 throttleFirst 操作符来解决按钮被多次点击的问题。throttleFirst允许设置一个时间长度,之后它会发送固定时间长度内的第一个事件,而屏蔽其它事件,在间隔达到设置的时间后,可以再发送下一个事件,如下图所示。

使用throttleFirst解决按钮多次响应的问题

同时,我们使用 RxBinding 将点击事件转化为一个Observable,将上述间隔时间设置为动画时间,这样,在点击按钮后只会弹出一个Fragment,避免了多次响应的问题。完整代码如下:

Button throttleFirstButton = (Button) findViewById(R.id.throttle_first_button);
RxView.clicks(throttleFirstButton)
.throttleFirst(ANIMATION_TIME, TimeUnit.MILLISECONDS)
.subscribe(aVoid -> {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction
.setCustomAnimations(R.animator.slide_up, R.animator.slide_down, R.animator.slide_up, R.animator.slide_down)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

transaction
.add(android.R.id.content, new DummyFragment())
.addToBackStack(DummyFragment.class.getSimpleName()).commit();
});

参考

  1. http://reactivex.io/RxJava/javadoc/rx/Observable.html#throttleFirst(long,%20java.util.concurrent.TimeUnit)
正文到此结束
Loading...