前言
自從用上RxJava后徹底迷上Rx系列響應(yīng)式編程胞谈,從本篇開始一起來學(xué)習(xí)一下Rx套餐之一的RxBinding尘盼。RxBinding是什么?它是一組開源庫烦绳,來自大神Jake Wharton之手卿捎,可將Android中各類UI控件的動作事件轉(zhuǎn)換為RxJava中的數(shù)據(jù)流。也就是說使用RxBinding径密,我們就可以以RxJava的形式來處理UI事件午阵。本篇主要講解其中RxView的相關(guān)View事件如何綁定。
RxBinding中主要包含RxView、RxTextView底桂、RxAdapterView植袍、RxCompoundButton等等。由于全寫一起篇幅太長籽懦,我就一篇講解一種了于个。本系列主要講解以上常用的4種,詳細(xì)內(nèi)容可飛機(jī)到:
依賴
本系列圍繞我自己編寫的RxBindingDemo來進(jìn)行講解暮顺,項目中主要使用ButterKnife做View注入厅篓,RxBinding做事件綁定。RxBindingDemo代碼在文末有給地址捶码。
注意:RxBinding包中包含RxJava的內(nèi)容贷笛,所以就無需再添加RxJava的依賴了。
dependencies {
......
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
BaseActivity
相信學(xué)習(xí)過RxJava的碼友一定記得宙项,使用RxJava實例化的Disposable需在不用時及時銷毀乏苦。
由于每個Activity中都寫一套add與clear的方法會造成代碼冗余,所以我將它們封裝到BaseActivity中方便統(tǒng)一對Disposable進(jìn)行管理尤筐,以及ButterKnife的統(tǒng)一綁定與解綁汇荐。
獻(xiàn)上代碼:
public abstract class BaseActivity extends AppCompatActivity {
public CompositeDisposable mCompositeDisposable;
private Unbinder mUnbinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutId());
mUnbinder = ButterKnife.bind(this);
mCompositeDisposable = new CompositeDisposable();
onViewCreated(savedInstanceState);
}
/**
* 添加訂閱
*/
public void addDisposable(Disposable mDisposable) {
if (mCompositeDisposable == null) {
mCompositeDisposable = new CompositeDisposable();
}
mCompositeDisposable.add(mDisposable);
}
/**
* 取消所有訂閱
*/
public void clearDisposable() {
if (mCompositeDisposable != null) {
mCompositeDisposable.clear();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
clearDisposable();
mUnbinder.unbind();
}
protected abstract int getLayoutId();
protected abstract void onViewCreated(Bundle savedInstanceState);
}
click點擊事件
clicks
RxView.clicks(View view)
,通過源碼可發(fā)現(xiàn)其內(nèi)部封裝了View.OnClickListener點擊監(jiān)聽盆繁,調(diào)用clicks方法返回一個Observable對象掀淘,每當(dāng)點擊這個View的時候,該Observable對象就會發(fā)射一個事件油昂,隨即調(diào)用onNext()方法革娄,Observable對應(yīng)的觀察者就可以通過onNext()回調(diào)響應(yīng)此次點擊事件。使用RxBinding還可做到點擊防抖的效果冕碟。來看代碼:
addDisposable(RxView.clicks(btnClick)
.throttleFirst(2, TimeUnit.SECONDS)
.subscribe(o -> {
Log.e("rx_binding_test", "clicks:點擊了按鈕:兩秒內(nèi)防抖");
}));
throttleFirst(long windowDuration, TimeUnit unit)
拦惋,設(shè)置一定時間內(nèi)只響應(yīng)首次(throttleFirst)或者末次(throttleLast)的點擊事件。windowDuration為防抖時間安寺,unit為時間單位厕妖。調(diào)用這個方法便可防止短時間內(nèi)對View的重復(fù)點擊,本例中設(shè)置的防抖時間為2s挑庶。從代碼看來是不是方便又簡潔呢言秸,以往實現(xiàn)防抖還得添加各種標(biāo)記,忒麻煩迎捺。
longClicks
RxView.longClicks(View view)
举畸,內(nèi)部封裝了View.OnLongClickListener長按監(jiān)聽,原理同上凳枝。
addDisposable(RxView.longClicks(btnClick)
.subscribe(o -> {
Log.e("rx_binding_test", "longClicks:長點擊了按鈕");
}));
draw繪制事件
RxView.draws(View view)
抄沮,內(nèi)部封裝了OnDrawListener繪制監(jiān)聽。
//點擊btnDraw調(diào)用viewCanvas的繪制
addDisposable(RxView.clicks(btnDraw)
.throttleFirst(2, TimeUnit.SECONDS)
.subscribe(o -> {
//此處可模擬讓viewCanvas繪制
//viewCanvas.getViewTreeObserver().dispatchOnDraw();
}));
//當(dāng)viewCanvas繪制時觸發(fā)
addDisposable(RxView.draws(viewCanvas)
.subscribe(o -> {
Log.e("rx_binding_test", "draws:viewCanvas繪制了");
}));
drag拖拽事件
RxView.drags(View view)
,內(nèi)部封裝了OnDragListener拖拽監(jiān)聽合是。
//當(dāng)btnDraw被拖拽時觸發(fā)
addDisposable(RxView.drags(btnDraw)
.subscribe(o -> {
Log.e("rx_binding_test", "drags:btnDraw被拖拽了");
}));
layoutChange布局改變事件
RxView.layoutChanges(View view)
,內(nèi)部封裝了OnLayoutChangeListener布局改變監(jiān)聽锭环。
//點擊btnChange改變btn_layout的布局,防抖2s
addDisposable(RxView.clicks(btnChange)
.throttleFirst(2, TimeUnit.SECONDS)
.subscribe(o -> btnLayout.layout(btnLayout.getLeft() - 20,
btnLayout.getTop(), btnLayout.getRight() - 20, btnLayout.getBottom())
));
//btn_layout布局改變時觸發(fā)
addDisposable(RxView.layoutChanges(btnLayout)
.subscribe(o -> {
Log.e("rx_binding_test", "layoutChanges:btnLayout布局改變了");
}));
scrollChange滑動事件
RxView.scrollChangeEvents(View view)
聪全,內(nèi)部封裝了OnScrollChangeListener滑動監(jiān)聽。
//點擊btnScroll模擬讓btnScrollLayout滑動
addDisposable(RxView.clicks(btnScroll)
.throttleFirst(2, TimeUnit.SECONDS)
.subscribe(o -> {
x += 10;
if (x == 100) {
x = 0;
}
btnScrollLayout.scrollTo(x, 0);
}));
//btnScrollLayout滑動時觸發(fā)
addDisposable(RxView.scrollChangeEvents(btnScrollLayout)
.subscribe(event -> {
Log.e("rx_binding_test", "scrollChangeEvents:btnScrollLayout滑動了:" + event.toString());
}));
View操作
RxView中還封裝了一些常用的例如setVisibility()
辅辩、setClickable()
等View操作难礼。使用起來也很簡單,如下:
addDisposable(RxView.clicks(btnClick)
.throttleFirst(2, TimeUnit.SECONDS)
.subscribe(o -> {
RxView.visibility(btnClick).accept(true);
RxView.clickable(btnClick).accept(true);
RxView.enabled(btnClick).accept(true);
}));
這種操作方法單獨使用是需要進(jìn)行try-catch的玫锋,但還記得RxJava2系列中我們學(xué)習(xí)到蛾茉,RxJava2的Action與Function的回調(diào)方法中都默認(rèn)throws Exception,RxBinding也是如此撩鹿。所以在觀察者中調(diào)用就無需try-catch了谦炬。
更多的操作可在RxView的源碼中查到,基本上View中有的节沦,J大神都編寫了键思,膜拜大神。
取消訂閱
最后別忘了在Activity銷毀時對創(chuàng)建的Disposable取消訂閱甫贯。Demo中的Act都以BaseActivity為基類吼鳞,所以就無需再調(diào)用取消訂閱了,BaseActivity已經(jīng)將這些工作做好了叫搁。
總結(jié)
RxBinding使用起來非常簡單赔桌,RxView中還有attaches、detaches渴逻,focusChanges疾党,globalLayouts,hovers惨奕,touches等等就不一一演示了仿贬,碼友們可自行嘗試。
進(jìn)階中的碼猿一枚墓贿,寫的不對的地方歡迎大神們留言指正茧泪,有什么疑惑或者建議也可以在我Github上RxBindingDemo項目Issues中提出,我會及時回復(fù)聋袋。
附上Demo的地址:
RxBindingDemo
另外:歡迎光臨我的Hexo個人博客:Lei’s Blog