Jake Wharton的RxBinding
RxBinding系列之RxView(一)
RxBinding
可將Android
中各類UI
控件的動(dòng)作事件
轉(zhuǎn)換為RxJava
中的數(shù)據(jù)流
坐慰。也就是說(shuō)可以使用RxBinding
以RxJava
的形式來(lái)處理UI
事件孩哑。本篇主要講解其中RxView
的相關(guān)View
事件如何綁定坟奥。
RxBinding
中主要包含RxView、RxTextView耘柱、RxAdapterView恐疲、RxCompoundButton
等等让禀。
Platform bindings:
implementation 'com.jakewharton.rxbinding3:rxbinding:3.0.0-alpha2'
AndroidX library bindings:
implementation 'com.jakewharton.rxbinding3:rxbinding-core:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-appcompat:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-drawerlayout:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-leanback:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-recyclerview:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-slidingpanelayout:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-swiperefreshlayout:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-viewpager:3.0.0-alpha2'
Google 'material' library bindings:
implementation 'com.jakewharton.rxbinding3:rxbinding-material:3.0.0-alpha2'
click點(diǎn)擊事件
clicks
throttleFirst(long windowDuration, TimeUnit unit)
屁桑,設(shè)置一定時(shí)間內(nèi)只響應(yīng)首次(throttleFirst
)或者末次(throttleLast
)的點(diǎn)擊事件。windowDuration
為防抖時(shí)間赵讯,unit
為時(shí)間單位盈咳。調(diào)用這個(gè)方法便可防止短時(shí)間內(nèi)對(duì)View
的重復(fù)點(diǎn)擊,本例中設(shè)置的防抖時(shí)間為 1s
边翼。
RxView.clicks(mLoginButton)
//1秒鐘之內(nèi)只取一個(gè)點(diǎn)擊事件鱼响,防抖操作
.throttleFirst(1, TimeUnit.SECONDS)
.subscribe(new Consumer<Unit>() {
@Override
public void accept(Unit unit) throws Exception {
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
});
longClicks
RxView.longClicks(View view)
,內(nèi)部封裝了View.OnLongClickListener
長(zhǎng)按監(jiān)聽(tīng)组底,原理同上丈积。
RxView.longClicks(mLoginButton)
.subscribe(new Consumer<Unit>() {
@Override
public void accept(Unit unit) throws Exception {
Log.i(TAG, "accept: longClicks-test");
}
});
RxTextView
/**
* accept: rxbindg_test before0-start-0-textxx
* accept: rxbindg_test before12-start-12-textxx
*/
RxTextView.textChangeEvents(mPswEditText)
.subscribe(new Consumer<TextViewTextChangeEvent>() {
@Override
public void accept(TextViewTextChangeEvent textViewTextChangeEvent) throws Exception {
Log.i(TAG, "accept: rxbindg_test before"+textViewTextChangeEvent.getStart()
+"-start-"+textViewTextChangeEvent.getStart()
+"-text"+textViewTextChangeEvent.getText()+"count"+textViewTextChangeEvent.getCount());
}
});
RxTextView
結(jié)合combineLatest
操作符:
應(yīng)用場(chǎng)景:登錄時(shí)滿足所有條件下,登錄按鈕才可以點(diǎn)擊
說(shuō)明:監(jiān)聽(tīng)多個(gè)被觀察者是否變化债鸡,在一個(gè)地方進(jìn)行統(tǒng)一驗(yàn)證江滨,如果驗(yàn)證成功,那么允許用戶進(jìn)行下一步的操作厌均,否則提示用戶輸入不正確唬滑,有任意一個(gè)被觀察者發(fā)生改變時(shí),會(huì)去取 其它 Observable
最近一次發(fā)射的數(shù)據(jù)棺弊,回調(diào)到函數(shù)當(dāng)中晶密。combineLatest
就被觸發(fā)連接幾個(gè)被觀察者進(jìn)行校驗(yàn)。
比如以下的兩個(gè)被觀察者镊屎,啟動(dòng)APP并沒(méi)有再用戶名和密碼輸入框中輸入數(shù)據(jù)惹挟,但是此時(shí)這兩個(gè)控件已被監(jiān)聽(tīng)茄螃,相當(dāng)于所有的Observable都至少發(fā)射過(guò)一個(gè)數(shù)據(jù)項(xiàng)缝驳,監(jiān)聽(tīng)結(jié)果為空直接觸發(fā)apply
事件,輸入用戶名時(shí)被觀察者nameObservable
發(fā)生變化,也直接觸發(fā)apply
事件用狱。
private void initFilter() {
InitialValueObservable<CharSequence> nameObservable = RxTextView.textChanges(userNameEditText);
InitialValueObservable<CharSequence> pwdObservable = RxTextView.textChanges(userPwdEditText);
InitialValueObservable<CharSequence> checkBoxObservable = RxTextView.textChanges(userPwdEditText);
nameObservable.subscribe(new Consumer<CharSequence>() {
@Override
public void accept(CharSequence charSequence) throws Exception {
String txt = charSequence.toString();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
});
Observable.combineLatest(nameObservable, pwdObservable, new BiFunction<CharSequence, CharSequence, Boolean>() {
@Override
public Boolean apply(CharSequence charSequence, CharSequence charSequence2) throws Exception {
boolean isEnnable = !TextUtils.isEmpty(userNameEditText.getText().toString()) && !TextUtils.isEmpty(userPwdEditText.getText().toString());
Log.i(TAG, "apply: " + isEnnable);
return isEnnable;
}
}).subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
Log.i(TAG, "accept: " + aBoolean);
if (aBoolean) {
loginButton.setBackgroundColor(0xffFF0000);
loginButton.setClickable(true);
} else {
loginButton.setBackgroundColor(0xff00FF00);
loginButton.setClickable(false);
}
}
});
Observable.combineLatest(mobileObservable, passwordObservable, new BiFunction<CharSequence, CharSequence, Object>() {
@Override
public Object apply(CharSequence mobile, CharSequence password) throws Exception {
Log.d(TAG,"合并事件訂閱 "+mobile+" "+password);
//手機(jī)號(hào)运怖、短信驗(yàn)證碼、勾選框 都符合條件時(shí)夏伊,才允許點(diǎn)擊登錄
if(!TextUtils.isEmpty(mobile) && !TextUtils.isEmpty(password)){
loginButton.setClickable(true);
loginButton.setBackgroundResource(R.drawable.basic_login_bg02);
}else{
loginButton.setClickable(false);
loginButton.setBackgroundResource(R.drawable.basic_login_bg01);
}
return new Object();
}
}).subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(activityContext, Lifecycle.Event.ON_DESTROY)))
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {}
});