RxBinding解析,顺便模仿RxBinding做个RxAnimation

RxBinding 是一个对android View各种事件的扩展库,把各种view事件转为Observable事件流,使得可以对view事件使用rxjava的各种操作,同时也简化了代码。
.

本文重点:

1.常用的使用场景 (ps: 懂得直接跳过!)

2.要注意的点(比较重要)

3.RxBinding实现分析

4.模仿RxBinding做一个RxAnimation

.

常用的使用场景:

.
1.各种点击事件的去重, 在RxBinding没有出来之前,你可能在开发过程中会遇到这种情况, 比如说点击某个按钮跳转到一个新的Activity, 暂且叫它A吧, 那么你快速点击这个按钮两次,你会发现A创建了两个实例。坑啊!

RxBinding 极好的解决了这个问题!

RxView.clicks(xxButton)
                .throttleFirst(500, TimeUnit.MILLISECONDS)
                .subscribe(new Action1() {
                    @Override
                    public void call(Void aVoid) {
                        startActivity(new Intent(MainActivity.this, A.class));
                    }
                });

RxAdapterView.itemClicks(listView)
                .throttleFirst(500, TimeUnit.MILLISECONDS)
                .subscribe(new Action1() {
                    @Override
                    public void call(Void aVoid) {
                        startActivity(new Intent(MainActivity.this, A.class));
                    }
                });

.
2.使得代码更简洁,特别是各种View的接口,特别是多个方法的那种,我本来想以TextView为示例的,算了这个都满天飞了,换一个比如SeekBar的监听事件的接口,你可能只需要onProgressChanged(); 但是你不得不把另外两个方法实现!

RxBinding解析,顺便模仿RxBinding做个RxAnimation_第1张图片
Paste_Image.png
但是用了RxBinding,你只需要这样写!
//这里只传递了进度
RxSeekBar.changes(seekbar)
                .subscribe(new Action1() {
            @Override
            public void call(Integer integer) {
                
            }
        })

3.RxBinding支持对点击事件的多次监听并且实现起来非常简单。RxBinding本身不能做到,但它与RxJava的操作方法结合可以做到,如:publish(), share(), replay()

Button b = (Button) v.findViewById(R.id.button);
Observable observable= RxView.clicks(b).share();

Subscription s = observable.subscribe(new Action1() {
            @Override
            public void call(Void aVoid) {
                // do something
            }
        });
compositeSubscription.add(s);

Subscription s1 = observable.subscribe(new Action1() {
            @Override
            public void call(Void aVoid) {
                // do something
            }
        });
compositeSubscription.add(s1);

4.各种View的常用事件,RxBinding都支持!, 还有appcompat-v7 ,design, 等等也都有单独的支持包!

Paste_Image.png

RxBinding解析,顺便模仿RxBinding做个RxAnimation_第2张图片
Paste_Image.png

.

要注意的点

RxBinding可能造成内存泄漏,所以最好手动取消订阅!
.

Subscription s1 = observable.subscribe(new Action1() {
            @Override
            public void call(Void aVoid) {
                // do something
            }
        });
compositeSubscription.add(s1);


//Acivity退出时 释放
Protected void OnDestory(){
    s1.unScribe();
}


或者使用RxLifeCycle, 这个库就是用来解决RxJava带来的内存泄漏!

如何使用readme里也比较清楚了。
地址: https://github.com/trello/RxLifecycle

RxBinding实现分析

RxBinding的实现其实比较简单: 借鉴一句话,就是语法糖,但是这糖真的好吃啊!!!

先说下大概的结构:

1.对用View的各种基础事件如点击事件,拖拽事件都是封装在RxView里的,类似的还有RxViewGroup
2. 对于某个View特有的事件封装在对应名称的类中,如RxTextView(TextWatcher), RxSeekBar, RxToolBar等等
3.对于各种单个参数的或者无参数的事件(如OnClickListener), 都封装为XXXXXOnSubscribe , 比如:ViewClickOnSubscribe
对于多个参数的事件都先把参数封装为xxxxEvent, 如:TextViewAfterTextChangeEvent

然后再封装一个XXXXOnSunscribe, 这就等同于ViewClickOnSubscribe了:

你可能会问,神经啊,为甚非要封装成Event,传递单个参数, 莫急后面你就明白了!

拿个最简单的点击事件做例子简单分析下:

RxBinding解析,顺便模仿RxBinding做个RxAnimation_第3张图片
Paste_Image.png

可以看到继承了Observable.OnSubscribe其实就是一个Action1:

RxBinding解析,顺便模仿RxBinding做个RxAnimation_第4张图片
Paste_Image.png

然后,在call方法里,检测了当前是否为UI线程,不是的话抛出异常,否则view添加了OnClickListener, onClick调用了onNext();

然后说说这个MainThreadSubscription:

之前写了一篇文章: RxAndroid深入理解 http://www.jianshu.com/p/8292ea39c38e

留下了一个尾巴:MainThreadSubscription

贴上代码:

RxBinding解析,顺便模仿RxBinding做个RxAnimation_第5张图片
Paste_Image.png
RxBinding解析,顺便模仿RxBinding做个RxAnimation_第6张图片
Paste_Image.png

主要看unsubscribe方法, 这个方法就是取消订阅时做的事,该方法首先判断了是否为UI线程,是的话调用了onUnsubscribe();方法,非UI线程的话,调用了AndroidSchedulers.mainThread():

Paste_Image.png

Paste_Image.png

实际上调用了LooperScheduler的createWorker(), createWorker()实际上创建了一个叫HandlerWorker的类,之前那边文章也讲了,如果看的觉得理不清,看看我之前的那篇文章HandlerWorker其实就是持有一个根据用户传递给LooperScheduler的Looper所创建的Handler, 然后SechduleAction 把这里的action0:


RxBinding解析,顺便模仿RxBinding做个RxAnimation_第7张图片
Paste_Image.png

包装成一个Runnable, 让handler发送到所在线程! 从而被执行!

但是因为AndroidSchedulers.mainThread()传递的就是Looper.getMainLooper(),即UI线程的Looper

所以在非UI线程的情况下, onUnsubscribe();方法也只会在UI线程执行!

.

RxAnimation实现

.
这是我自己模仿RxBinding实现的对动画的各种事件的处理! 其实很简单!
地址:https://github.com/niniloveyou/RxJava-learn

.有兴趣的看看!!!


RxBinding解析,顺便模仿RxBinding做个RxAnimation_第8张图片
Paste_Image.png

比如我想在渐变动画执行完的时候做些什么! 就可以这样写了!

RxAnimation.onEnd(animation)
                .subscribe(new Action1() {
            @Override
            public void call(Animation animation) {
                // do something
            }
        });

或者valueAnimator/ObjectAnimator

//update
RxAnimator.onUpdate(animator)
                .subscribe(new Action1() {
            @Override
            public void call(Float value) {
                //do something
            }
        });

这波装的可以吧! 可以你就点个赞。

1480384285107708.gif

你可能感兴趣的:(RxBinding解析,顺便模仿RxBinding做个RxAnimation)