封裝那些事-RecyclerView封裝實(shí)踐

今天要跟大家安利一種封裝方式,保證只用100行代碼就能擼一個(gè)列表頁(yè)面掩浙。

來(lái)上圖:


recycler01.png

recycler02.png

相關(guān)說(shuō)明:

  1. 該列表頁(yè)可以是Activity谣妻,也可以是Fragment
  2. 該列表頁(yè)使用RecyclerView鳞滨,所以支持列表累盗,網(wǎng)格寒矿,瀑布流
  3. 該列表頁(yè)支持下拉刷新,自動(dòng)加載更多
  4. 該列表需extends BaseListActivity或BaseListFragment

之前Stay寫(xiě)過(guò)一篇RecyclerView再封裝若债,本篇是對(duì)該篇的詳細(xì)解釋符相。

本文難度適中,沒(méi)有過(guò)多的算法拆座,純粹是利用Android提供的API與一些設(shè)計(jì)模式相結(jié)合做的封裝主巍。

沒(méi)什么好解釋的了,老司機(jī)要開(kāi)車?yán)才泊眨蔚卧兴鳌!?/p>

首先來(lái)看看我們這個(gè)列表SampleListActivity, 它是繼承BaseListActivity

    public class SampleListActivity extends BaseListActivity<String> 

注意躏碳,此處有泛型搞旭。這里的T就是你用在列表數(shù)據(jù)List<T>。為什么要這樣寫(xiě)菇绵,先埋個(gè)坑肄渗,一會(huì)再填

在SampleListActivity中

    @Override
protected BaseViewHolder getViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_sample_list_item, parent, false);
    return new SampleViewHolder(view);
}

@Override
protected ILayoutManager getLayoutManager() {
    return new MyGridLayoutManager(getApplicationContext(), 3);
}

class SampleViewHolder extends BaseViewHolder {
}

子類SampleListActivity只需要做以上實(shí)現(xiàn)

  1. 指定列表類型:linear, grid, stagger
  2. 指定item對(duì)應(yīng)的ViewHolder
  3. ViewHolder的數(shù)據(jù)綁定

ok咬最,只要完成這些事情翎嫡,一個(gè)妹子列表就出來(lái)了。開(kāi)擼吧永乌。

好奇的你不會(huì)就此滿足惑申。Adapter哪去了?RecyclerView呢翅雏?我怎么沒(méi)看到它們圈驼。嗯哼~

BaseListActivity有個(gè)兒子叫SampleListActivity, 兒子非常努力,憑借自己的天賦找到了組織望几,終于绩脆,3秒后,兒子拿著請(qǐng)求來(lái)的數(shù)據(jù)加上老爹給的框架擼上了妹紙橄抹。注:妹紙圖來(lái)自gank.io

就是這樣一個(gè)情況靴迫,除了請(qǐng)求數(shù)據(jù)以及制定每個(gè)Item的UI樣式,其他的都由父類完成楼誓。

是不是好奇BaseListActivity中封裝了些什么玉锌?我們進(jìn)去看看吧。

recycler03.png

其實(shí)SampleListActivity還有個(gè)爺爺慌随,不過(guò)這不重要芬沉。我們看躺同,在父類中定義了ArrayList<T>, Adapter, Recycler. 并且對(duì)Recycler, Adapter做了初始化,為什么要這樣寫(xiě)丸逸?老司機(jī)帶你看一下系統(tǒng)源碼就知道了蹋艺。

    android.app.ListActivity
recycler04.png

這里實(shí)際上參考了系統(tǒng)ListActivity的初衷,將ListView(這里是RecyclerView)封裝起來(lái)黄刚,并且定義一個(gè)默認(rèn)layout捎谨,當(dāng)列表頁(yè)非常簡(jiǎn)單時(shí),子類只需要綁定data就可以完成UI顯示憔维。

Stay這里做的BaseListActivity要更內(nèi)聚一些涛救。因?yàn)槲覀儗ist<T>定義在父類,所以在Adapter的getItemCount中可以直接做返回业扒。不需要子類明確指定size检吆。至于其它父類定義不了的,比如onCreateViewHolder, onBindViewHolder程储,可以讓子類實(shí)現(xiàn)蹭沛。

還有父類預(yù)定義了列表樣式,默認(rèn)為L(zhǎng)inearLayoutManager章鲤,如果子類不想要摊灭,直接重寫(xiě)方法就可以了。

其實(shí)這個(gè)父類代碼也不多败徊,90行帚呼。父類有父類的想法,為了兒子能自己獨(dú)立成長(zhǎng)皱蹦,只能提供一些最基礎(chǔ)的框架煤杀,至于兒子以后能干嘛,那是兒子的事情根欧。

雖然父類做的事情不多怜珍,但是能給的都給了端蛆,它做的最正確的事凤粗,就是早年還做了一套封裝,它叫PullRecycler今豆。這個(gè)PullRecycler還挺給力的嫌拣,可以下拉刷新,自動(dòng)加載更多呆躲,支持三種LayoutManager异逐。

其實(shí)這個(gè)PullRecycler沒(méi)有多難做,也就是一個(gè)SwipeRefreshLayout+RecyclerView插掂。當(dāng)然難點(diǎn)還是有的灰瞻。下拉刷新是SwipeRefreshLayout實(shí)現(xiàn)的腥例,但是自動(dòng)加載更多有三個(gè)坑。

  1. 判斷是否需要加載更多酝润,是通過(guò)onScrollListener來(lái)做的燎竖,你需要拿屏幕中最后一個(gè)顯示的item posistion去跟totalCount比對(duì)。但是在StaggerLayoutManager中要销,拿到的是一個(gè)數(shù)組构回。其它LayoutManager拿到的是int。這就坑了疏咐,不統(tǒng)一纤掸,很多github上的RecyclerView封裝都是通過(guò)instanceOf來(lái)強(qiáng)轉(zhuǎn)的,我不太喜歡浑塞。所以我就定義了一個(gè)接口ILayoutManager借跪,讓每個(gè)LayoutManager去實(shí)現(xiàn)一個(gè)統(tǒng)一的findLastVisiblePosition()
    recycler05.png
  2. 加載更多footer需要自成一行,但在grid和stagger模式下酌壕,這個(gè)就比較麻煩了垦梆。GridLayoutManager還簡(jiǎn)單一點(diǎn),直接看源碼的類注釋你就能知道如何做仅孩。SpanSizeLookup托猩,如果為footer,那就返回1辽慕,代表占滿整個(gè)寬度京腥。
    recycler06.png

    StaggerGridLayoutManager更麻煩,你得改itemView的LayoutParams溅蛉,將setFullSpan設(shè)為true公浪,才能自成一行。
    recycler07.png
    recycler08.png
  3. 以前ListView可以添加footer船侧,但是RecyclerView沒(méi)有欠气,你得自己在adapter中做判斷,如果有footer镜撩,那itemCount要+1预柒。所以我又將Adapter抽出來(lái),做成BaseListAdapter袁梗,是否顯示footer宜鸯,判斷是否是stagger模式下footer,給一個(gè)默認(rèn)footerViewHolder遮怜,如果子類不滿意還能再重寫(xiě)淋袖。
    recycler09.png

啊啊啊,開(kāi)車好累锯梁,老司機(jī)得歇會(huì)即碗。

附上源碼github焰情,自己拿去開(kāi)吧。直接可以運(yùn)行剥懒,另外還封裝了BaseSectionListActivity, 帶section header的sample烙样。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蕊肥,隨后出現(xiàn)的幾起案子谒获,更是在濱河造成了極大的恐慌,老刑警劉巖壁却,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件批狱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡展东,警方通過(guò)查閱死者的電腦和手機(jī)赔硫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)盐肃,“玉大人爪膊,你說(shuō)我怎么就攤上這事≡彝酰” “怎么了推盛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)谦铃。 經(jīng)常有香客問(wèn)我耘成,道長(zhǎng),這世上最難降的妖魔是什么驹闰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任瘪菌,我火速辦了婚禮,結(jié)果婚禮上嘹朗,老公的妹妹穿的比我還像新娘师妙。我一直安慰自己,他們只是感情好屹培,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布默穴。 她就那樣靜靜地躺著,像睡著了一般惫谤。 火紅的嫁衣襯著肌膚如雪壁顶。 梳的紋絲不亂的頭發(fā)上珠洗,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天溜歪,我揣著相機(jī)與錄音,去河邊找鬼许蓖。 笑死蝴猪,一個(gè)胖子當(dāng)著我的面吹牛调衰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播自阱,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼嚎莉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了沛豌?” 一聲冷哼從身側(cè)響起趋箩,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎加派,沒(méi)想到半個(gè)月后叫确,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芍锦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年竹勉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娄琉。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡次乓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出孽水,到底是詐尸還是另有隱情票腰,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布女气,位于F島的核電站丧慈,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏主卫。R本人自食惡果不足惜逃默,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望簇搅。 院中可真熱鬧完域,春花似錦、人聲如沸瘩将。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)姿现。三九已至肠仪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間备典,已是汗流浹背异旧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留提佣,地道東北人吮蛹。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓荤崇,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親潮针。 傳聞我的和親對(duì)象是個(gè)殘疾皇子术荤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,504評(píng)論 25 707
  • 又到了更新博文的時(shí)間了,最近在看一本很不錯(cuò)的心理學(xué)書(shū)籍每篷,名字叫做 《拖延心理學(xué)》瓣戚,封面長(zhǎng)下面這樣子 書(shū)的內(nèi)容主要是...
    ec95b5891948閱讀 57,434評(píng)論 38 472
  • RecyclerView做為L(zhǎng)istView的替代品,已經(jīng)出了很久了焦读,既然是替代品带兜,那自然有些ListView沒(méi)有...
    stay4it閱讀 7,302評(píng)論 3 27
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 46,708評(píng)論 22 664
  • 我是小馬哥喧兄,也是草房居士无畔,茫茫人海中普通的再也不能普通的人。 我愛(ài)音樂(lè)吠冤,愛(ài)美食浑彰,愛(ài)旅游,愛(ài)幻想拯辙,熱愛(ài)一切關(guān)乎生命的...
    奧巴馬吃雞腿閱讀 927評(píng)論 2 0