MTRVA2.0來啦

前言

從MTRVA的誕生到如今已經有一段時間了,當初第一個版本出來以後,我是很激動的,這能夠說是我真正意義上的第一次創做,也是本身的一次歷史性進步,寫到這,又想起本身熬夜更新版本,躺在牀上呆呆地思考着哪裏須要優化修改...太多太多的回憶,那麼MTRVA做爲RecyclerViewAdapter的一股清流,到底有什麼鳥用呢?html

特色

  • 使用簡單快捷,可配合大多數Adapter
  • 一行代碼刷新單個level,可對應多個type,刷新帶有動畫
  • 支持增刪改查操做
  • 支持異步,高頻率刷新,可擴展(如配合RxJava)
  • 單個level支持Loading(加載),Empty(空),Error(錯誤)頁面切換
  • 單個level支持header,footer
  • 單個level支持展開和合攏(可設置合攏最小值)
  • 支持加載全局Loading(加載)頁面
  • 支持註解生成類,減小工做量
  • 支持刷新生命週期回調
  • 兼容低版本RecyclerView
  • 進階用法,好比打造本身的headerView和footerView,讓頁面在多種頁面之間自由切換

思想

這是MTRVA的架構圖。android

咱們先想象這樣一個常見的場景(列表頁),那麼咱們首先要寫一個Adapter,而後針對咱們每個type寫一個xml,其次咱們要在Adapter中用一個list來控制item數量以及每一個item渲染所須要的實體類等等,若是對原有list插入邏輯很複雜,甚至複雜到要控制type的start和end的position,可能最初寫邏輯代碼的時候你很快寫完了,幸運的是也沒報錯。悲劇的是過了幾個月,忽然報錯了,再回去看的時候,我相信你會和我同樣,心情只能「臥槽」來形容。或者在一堆type控制position的代碼中再加一個type,對不起,我選擇辭職。git

固然,辭職是開玩笑的,MTRVA這時候就發揮做用啦,在這裏,你不用擔憂數據邏輯處理(並且這些處理也不該該寫在你的業務層代碼中),你只要關心你的UI邏輯,而這些是你應該關心的,也必須關心的,也必須用心寫的,由於咱們的業務不同,咱們不同。程序員

那麼機智的同窗確定要問,既然MTRVA是控制數據處理的,那是否是相似一個Helper類與Adapter組合使用,仍是傳統的改造Adapter的架構達到目的?這個問題水平很高,獎勵你一個女友,MTRVA另外一大亮點是與Adapter配合使用,只要你的Adapter是RecyclerViewAdapter,那麼基本能夠和MTRVA配合使用,若是有不能配合的,請聯繫我,我儘可能不影響你項目Adapter的使用。github

這裏有個小插曲,有幾個同窗反映即便只寫UI邏輯,若是type夠多的話,代碼依然很複雜,這其實不難,你能夠定義一個處理UI邏輯的接口,針對於不一樣type實現接口,把不一樣type的UI邏輯給抽離出來,甚至能夠複用。若是腦中仍是沒有一個清晰的模型,能夠參考個人demo,這是我應該作的(手動滑稽),但不要照搬,適合本身的纔是最好的。api

實戰

關於實戰我是真的不想再寫了,由於實在太簡單了,這裏給出我在掘金髮的一篇文章《BRVAH+MTRVA,複雜?不存在的》以及MTRVA的文檔,看不懂的你打死我,而此次主要想寫的是2.0更新了什麼?若是我項目已經集成了MTRVA,我須要注意什麼?我更想寫的是這些,當初並不想發文章,但是我想着有些同窗可能用了一個版本以後,若是不是那個版本已經支持不了需求,是不會去更新版本的,用的好好的我幹嗎去更新啊?當這些同窗想更新的時候可能只能去看文檔,而文檔只有最新的使用方式,所以我秉承一向的做風,每次更新我都會寫一篇文章來闡述版本之間的差距,而此次屬於大版本更新,動靜稍微大了點。性能優化

這裏說個不少人問的問題,關於網格和線性混排的問題。這個其實不屬於個人範疇,但我確定會細心解答的,最簡單的就是嵌套,若是優雅一點能夠研究下類GridLayoutManager的setSpanSizeLookup方法,能夠參考這篇文章《RecyclerView:實現帶header的grid》bash

更新

既然是大版本更新,到底有什麼騷操做呢?架構

背景

咱們先從大方向來,此次改版的核心思想是從type的思惟定勢到level的重視和突破。這樣說可能有點抽象,俗話說的好,No picture,say a J8!咱們來看看2.0版本的佈局模型圖與1.0版本的比較。 異步

若是是老用戶會發現2.0版本的設計更符合咱們的初衷。此次的改版跟你們意見和建議有着密不可分的關係,一我的能力再強也是有限的(這樣誇本身真的好嗎),而團隊的力量是無限的,真的很感謝大家。

好了,咱們簡單分析一下,這爲何是突破。從1.0版本看,明明最外層定義的是level,而刷新的級別倒是type;註冊資源的時候,一個type去對應一個level,這是矯情嗎,我要這level有何用?若是兩種type同一level使用起來特別不方便,侷限性較大。而咱們再看2.0版本:

一種level能夠註冊多種type,在level裏面type數據的順序是無限制的,例如上面的type2在type1的中間,顯然是能夠無視順序,讓type1堆在一塊兒這種,這樣咱們的level可控制的UI更加豐富!雖然2.0版本以前也能實現,但對操做要求較高。

這是一次思想的突破,老是避免不了api的改動,而這時候就體現架構設計的重要性,你是一個一個去找出來再改仍是改一個地方就好了,你是要刪這刪那,仍是隻要添加類就好了...這是咱們的語言,而專業一點,你要牢記Java的六大設計原則,雖然我用的也不夠靈活,可是你不去用就永遠也不會用。

我猜有些同窗已經不耐煩了,能不能說重點,到底改了啥啊?兄臺,請放下你的40米大刀,我立刻說。

API差別

資源註冊

首先咱們從註冊資源開始,原來咱們是這樣的:

registerMoudle(ItemEntity3.TYPE_3)
                .level(2)
                .layoutResId(R.layout.item_3)
                .register();
複製代碼

而如今是這樣的:

registerMoudle(LEVEL_FIRST)
                .type(TypeOneItem.TYPE_ONE)
                .layoutResId(R.layout.item_first)
                .type(TypeTwoItem.TYPE_TWO)
                .layoutResId(R.layout.item_second)
                .register();
複製代碼

與上面說的同樣,以level爲主導,下面咱們能夠定義多個type,每一個type對應一個佈局xml,原來level的定義更多指的是type順序的等級,而其它諸如header、footer、loading等不變。

刷新方法

其次一系列的notify方法,原先的type參數所有改成level,這也是影響比較大的地方,若是你是按照個人建議把helper刷新方法封裝在adapter裏面,改起來也是so easy!瞧,這就是設計的魅力!

例如經常使用的這些方法:

public void notifyMoudleDataChanged(List<? extends T> data, int level);
public void notifyMoudleDataAndHeaderChanged(List<? extends T> data, T header, int level);
public void notifyMoudleDataAndHeaderAndFooterChanged(T header, List<? extends T> data, T footer, int level);
複製代碼

資源適配器

LoadingEntityAdapter修改點是同樣的,原先回調參數只有type,此次多加一個參數level,雖然二者只要得其一就能計算出另外一個。舉個栗子:

T createLoadingEntity(int type);===>T createLoadingEntity(int type, int level);
複製代碼

方法

  • getLevel方法從private改成public
  • 去除getCurrentRefreshType方法並用getCurrentRefreshLevel方法替換
  • 全局初始化loading(加載)類LoadingConfig以及相應Builder的setLoading方法參數type改成level
  • 新增getDataWithLevel方法,根據level拿到相對應的數據
  • 類HandleBase的type屬性修改成level,這也是意料之中的事情

註解

我不知道這玩意有人用嗎?反正先前版本已經分離出來了,若是想用要另外依賴庫,具體能夠看文檔。

關於註解的改動其實和上面差很少,主要把原先定義爲type的統統改成level,使用方法是不變的。

雜談

就改動這麼點東西?也要興師動衆嗎?Sorry,就這麼點東西,打擾了。甚至你能夠無腦記type改level,但...可是我底層邏輯的修改可慘了,我已經記不清我改了多少地方,我只記得我一直在瘋狂測試,生怕哪裏沒改動而影響升級了2.0版本的同窗使用。固然已經集成MTRVA的同窗並不必定要更新,此次是在架構上的一次改進,方便之後的擴展。若是跟我同樣,喜歡新版本的同窗能夠嘗試更新版本,這裏提供本身經常使用的更新新版本方法:首先下載官方提供的demo,瘋狂玩,玩demo不過癮的本身改代碼再玩,玩得差很少的時候就集成到項目中,瘋狂自測,沒問題以後與版本測試一塊兒交給咱們可愛的測試人員。若是有更好的方法能夠聯繫我,我改完告知你們,你們一塊兒學習。

細心的朋友發現咱們的篇幅並非很長,本次的主角就是MTRVA,就是一個庫,但對我來講是一種情懷。我先說說我本身選擇庫的標準,首先肯定庫的特色是什麼?對我如今的項目有什麼好處?我如今項目中有沒有相似的庫,相比較怎麼樣?若是我選擇使用,使用是否簡單,集成是否複雜,會不會對我項目有很大影響,後期做者是否維護等等。這是本身的想法,但願能幫到你,歡迎補充。

原本這個月發的文章主題是Android性能優化,以前公司是小公司(雖然如今仍是小公司),屬於需求完成就萬事大吉,但做爲一名優秀的程序員,對本身開發的應用要求僅僅知足需求,那也太low了,早晚被淘汰。下個月可能發佈我對性能優化的一點理解,但願對你們有所幫助,拭目以待!這裏插個嘴,個人項目CrazyDaily也跟着更新了,除了MTRVA的更新,還有替換內涵段子爲搞笑視頻,緣由你懂的!

這裏強調一點,我開源的庫我確定會一直更新下去,除非沒人用了或者我已經不在這行業了。雖然有時候多個用戶在同一段時間問了好幾個問題,有幾個仍是比較棘手的問題,本身也曾想過刪庫或者中止維護。但想一想別人用個人庫是對個人一種承認,是看得起我,同時知足本身微不足道的虛榮心,我瞬間就來勁了,哈哈,不知道這是否是自我催眠。之後開源庫可能會少寫,但開源的精神必須有,一些比較裝逼且實用的寫法我都會集成在個人項目CrazyDaily中,喜歡的朋友能夠star關注一波,劇透一波,將有一大波自定義控件與動畫涌入項目。

最最最重要的一點是,你們能夠在個人博客找到個人聯繫方式,隨便加,但不必定即時回覆,敬請諒解。經過好友後第一句不要叫我大佬(手動捂臉),我只是一隻開發Android的渣渣。有幾個同窗問我爲啥不組個羣啊?我相信你確定加了一堆的羣,有沒有用,你內心尚未一點13數嗎?有問題就直接問好了!可能你的問題我也沒碰到過,但我會盡力給你解決,你們一塊兒學習,何樂而不爲?固然能搜索到的就別來啦!

最後,感謝一直支持個人人!

傳送門

Github:github.com/crazysunj/M…

文檔:crazysunj.com/2017/08/14/…

相關文章
相關標籤/搜索