美文网首页Think AndroidAndroid实战
使用RxJava实现android里面的倒计时效果

使用RxJava实现android里面的倒计时效果

作者: sirai | 来源:发表于2018-03-17 21:15 被阅读182次
    image

    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();
            }
        }
    }
    
    /**
         * 使用RxJava1实现倒计时
         */
        private void countDown() {
            final long count = 30;
            Observable.interval(1, TimeUnit.SECONDS)
                    .take(31)//计时次数
                    .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("倒计时");
                        }
    
                        @Override
                        public void onError(Throwable e) {
    
                        }
    
                        @Override
                        public void onNext(Long aLong) {
                            cutdown.setText("倒计时" + aLong);
                        }
                    });
        }
    

    相关文章

      网友评论

        本文标题:使用RxJava实现android里面的倒计时效果

        本文链接:https://www.haomeiwen.com/subject/uvqsqftx.html