使用RxJava實(shí)現(xiàn)android里面的倒計(jì)時(shí)效果

image

intervalRange操作符

開始前我們先來了解下intervalRange操作符(了解過的可以忽哈)。
  intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit)

start:起始數(shù)值
count:發(fā)射數(shù)量
initialDelay:延遲執(zhí)行時(shí)間
period:發(fā)射周期時(shí)間
unit:時(shí)間單位
一句話簡介就是延遲initialDelay個(gè)unit單位后,以period為周期,依次發(fā)射count個(gè)以start為初始值并遞增的數(shù)字。

布局

布局中放一個(gè)Button用來演示點(diǎn)擊獲取驗(yàn)證碼,并開啟倒計(jì)時(shí)重新獲取的功能。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="15dp"
    tools:context="com.holmeslei.rxjava2demo.ui.CountDownActivity">

    <Button
        android:id="@+id/btn_get_code"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="獲取驗(yàn)證碼" />
</RelativeLayout>

Activity

由于業(yè)務(wù)邏輯簡單,所以就不整什么復(fù)雜的框架了,功能都在Activity中實(shí)現(xiàn)。

1.使用ButterKnife依賴注入獲取Button的實(shí)例及設(shè)置其點(diǎn)擊監(jiān)聽方法。
2.點(diǎn)擊Button后首先將其設(shè)置為不可點(diǎn)擊,然后初始化全局變量Disposable。
3.使用Flowable的intervalRange操作符,從0開始每隔1s發(fā)射一個(gè)自增的數(shù)字,持續(xù)11次,延遲0s執(zhí)行。這樣就設(shè)定好了10秒的倒計(jì)時(shí),可根據(jù)實(shí)際需要修改時(shí)長。
4.由于需要刷新UI,所以設(shè)定觀察者執(zhí)行在Android的UI線程。
5.在doOnNext的回調(diào)中更新Button的顯示UI,達(dá)到讀秒的效果。
6.在doOnComplete的完成回調(diào)中重新將Button設(shè)置為可點(diǎn)擊,然后設(shè)置顯示UI。
7.最后調(diào)用后subscribe()訂閱,這樣一個(gè)完整的異步事件流就完成了。
8.別忘了在Activity銷毀時(shí)將全局Disposable取消訂閱銷毀掉。使用RxJava將無用的Disposable及時(shí)銷毀是一個(gè)很好的習(xí)慣,否則后期就得忙著處理各種OOM異常啦。

public class CountDownActivity extends AppCompatActivity {
    @BindView(R.id.btn_get_code)
    Button btnGetCode;
    private Disposable mdDisposable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_count_down);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.btn_get_code)
    public void onViewClicked() {
        //點(diǎn)擊后置為不可點(diǎn)擊狀態(tài)
        btnGetCode.setEnabled(false);
        //從0開始發(fā)射11個(gè)數(shù)字為:0-10依次輸出,延時(shí)0s執(zhí)行,每1s發(fā)射一次。
        mdDisposable = Flowable.intervalRange(0, 11, 0, 1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        btnGetCode.setText("重新獲取(" + (10 - aLong) + ")");
                    }
                })
                .doOnComplete(new Action() {
                    @Override
                    public void run() throws Exception {
                        //倒計(jì)時(shí)完畢置為可點(diǎn)擊狀態(tài)
                        btnGetCode.setEnabled(true);
                        btnGetCode.setText("獲取驗(yàn)證碼");
                    }
                })
                .subscribe();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mdDisposable != null) {
            mdDisposable.dispose();
        }
    }
}
/**
     * 使用RxJava1實(shí)現(xiàn)倒計(jì)時(shí)
     */
    private void countDown() {
        final long count = 30;
        Observable.interval(1, TimeUnit.SECONDS)
                .take(31)//計(jì)時(shí)次數(shù)
                .map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long integer) {
                        return count - integer;
                    }
                })
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        cutdown.setEnabled(false);
                        cutdown.setBackgroundColor(Color.DKGRAY);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Long>() {

                    @Override
                    public void onCompleted() {
                        cutdown.setEnabled(true);
                        cutdown.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                        cutdown.setText("倒計(jì)時(shí)");
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Long aLong) {
                        cutdown.setText("倒計(jì)時(shí)" + aLong);
                    }
                });
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容