RxBinding系列之RxView(一)

前言

自從用上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ī)到:

Jake Wharton的RxBinding

依賴

本系列圍繞我自己編寫的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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末队伟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子幽勒,更是在濱河造成了極大的恐慌嗜侮,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異锈颗,居然都是意外死亡顷霹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門击吱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來淋淀,“玉大人,你說我怎么就攤上這事覆醇《浞祝” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵永脓,是天一觀的道長袍辞。 經(jīng)常有香客問我,道長常摧,這世上最難降的妖魔是什么搅吁? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮落午,結(jié)果婚禮上似芝,老公的妹妹穿的比我還像新娘。我一直安慰自己板甘,他們只是感情好党瓮,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盐类,像睡著了一般寞奸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上在跳,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天枪萄,我揣著相機(jī)與錄音,去河邊找鬼猫妙。 笑死瓷翻,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的割坠。 我是一名探鬼主播齐帚,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼彼哼!你這毒婦竟也來了对妄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤敢朱,失蹤者是張志新(化名)和其女友劉穎剪菱,沒想到半個月后摩瞎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡孝常,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年旗们,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片构灸。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡上渴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出冻押,到底是詐尸還是另有隱情驰贷,我是刑警寧澤盛嘿,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布洛巢,位于F島的核電站,受9級特大地震影響次兆,放射性物質(zhì)發(fā)生泄漏稿茉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一芥炭、第九天 我趴在偏房一處隱蔽的房頂上張望漓库。 院中可真熱鬧,春花似錦园蝠、人聲如沸渺蒿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茂装。三九已至,卻和暖如春善延,著一層夾襖步出監(jiān)牢的瞬間少态,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工易遣, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留彼妻,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓豆茫,卻偏偏與公主長得像侨歉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子揩魂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,506評論 25 707
  • Github:https://github.com/ReactiveX/RxJavahttps://github....
    才兄說閱讀 1,627評論 2 10
  • 前言 我從去年開始使用 RxJava 肤京,到現(xiàn)在一年多了颊艳。今年加入了 Flipboard 后茅特,看到 Flipboar...
    AWeiLoveAndroid閱讀 2,837評論 4 42
  • 天氣就這么逐漸冷了下來,北京變天的速度尤其的快棋枕,好多衣服沒來得及穿就再次被埋葬起來白修。我又是一個這么怕冷的人。 早上...
    ace其實是我閱讀 264評論 0 1
  • 巧克力是屋頂 餅干是墻壁 落下的凱凱白雪是鮮奶冰淇淋 覆蓋了卡布奇諾的大地 樹干上的冰棱奶糖一般美好 白雪公主降生...
    木偶Devil11閱讀 189評論 1 3