RxJava2系列實踐之倒數計時功能(三)

LeiHolmes發表於2019-02-26

前言

  通過本系列前兩篇的學習,相信各位碼友已經基本掌握RxJava2怎麼使用了,本篇我們一起來通過一個小例子實踐一下,也可以加深印象。來看看如何使用RxJava2的intervalRange操作符實現倒數計時功能。
  

依賴

  首先新增依賴,Demo中使用了ButterKnife注入,各版本以當前最新的為準。

dependencies {
    ......
    compile 'io.reactivex.rxjava2:rxjava:2.1.3'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'com.jakewharton:butterknife:8.7.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0'
}複製程式碼

intervalRange操作符

  彆著急上程式碼,開始前我們先來了解下intervalRange操作符(瞭解過的可以忽略哈)。
  intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit)

  • start:起始數值
  • count:發射數量
  • initialDelay:延遲執行時間
  • period:發射週期時間
  • unit:時間單位

  一句話簡介就是延遲initialDelay個unit單位後,以period為週期,依次發射count個以start為初始值並遞增的數字。

佈局

  佈局中放一個Button用來演示點選獲取驗證碼,並開啟倒數計時重新獲取的功能。

<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="獲取驗證碼" />
</RelativeLayout>複製程式碼

Activity

  由於業務邏輯簡單,所以就不整什麼複雜的框架了,功能都在Activity中實現。

  1. 第一步,使用ButterKnife依賴注入獲取Button的例項及設定其點選監聽方法。
  2. 第二步,點選Button後首先將其設定為不可點選,然後初始化全域性變數Disposable。
  3. 第三步,使用Flowable的intervalRange操作符,從0開始每隔1s發射一個自增的數字,持續11次,延遲0s執行。這樣就設定好了10秒的倒數計時,可根據實際需要修改時長。
  4. 由於需要重新整理UI,所以設定觀察者執行在Android的UI執行緒。
  5. 在doOnNext的回撥中更新Button的顯示UI,達到讀秒的效果。
  6. 在doOnComplete的完成回撥中重新將Button設定為可點選,然後設定顯示UI。
  7. 最後呼叫後subscribe()訂閱,這樣一個完整的非同步事件流就完成了。
  8. 別忘了在Activity銷燬時將全域性Disposable取消訂閱銷燬掉。使用RxJava將無用的Disposable及時銷燬是一個很好的習慣,否則後期就得忙著處理各種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() {
        //點選後置為不可點選狀態
        btnGetCode.setEnabled(false);
        //從0開始發射11個數字為:0-10依次輸出,延時0s執行,每1s發射一次。
        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 {
                        //倒數計時完畢置為可點選狀態
                        btnGetCode.setEnabled(true);
                        btnGetCode.setText("獲取驗證碼");
                    }
                })
                .subscribe();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mdDisposable != null) {
            mdDisposable.dispose();
        }
    }
}複製程式碼

執行效果

  最後看一下執行效果Gif。


  
執行效果
執行效果

總結

  本篇文章利用RxJava2演示了一個倒數計時的小栗子,更多的用法還待各位碼友去探索與發現哈。
  進階中的碼猿一枚,寫的不對的地方歡迎大神們留言指正,有什麼疑惑或者建議也可以在我Github上RxJava2Demo專案Issues中提出,我會及時回覆。
  附上RxJava2Demo的地址:
  RxJava2Demo

  另外:歡迎光臨我的Hexo個人部落格:Lei’s Blog

相關文章