Android開發(fā)之一些好用的RecyclerView輪子

1 Introduction

android.support.v7.recyclerview
在Android 5.0之后蕉斜,Google推出RecyclerView來取代ListView。官方是這樣介紹的:

A flexible view for providing a limited window into a large data set.

和ListView一樣茂翔,RecyclerView用于顯示列表形式的界面,并且通過復(fù)用View的方式來節(jié)約系統(tǒng)資源费就,甚至和ListView一樣通過Adapter來渲染數(shù)據(jù)过蹂。那么我們為什么要使用RecyclerView呢?自然要說下歪赢,二者的區(qū)別:

  1. RecyclerView自動地幫我們實現(xiàn)了itemView的重復(fù)利用,而強(qiáng)制開發(fā)者去繼承RecyclerView.ViewHolder來實現(xiàn)一個ViewHolder來管理與itemView相關(guān)的位置信息及其他數(shù)據(jù)单料。
  2. RecyclerView必須設(shè)置各種LayoutManager來實現(xiàn)GridView埋凯、ListView甚至瀑布流的效果。
  3. ListView擁有android:divider屬性輕松實現(xiàn)條目之間的統(tǒng)一分隔線扫尖,而RecyclerView需要一個RecyclerView.ItemDecoration對象來設(shè)置各種各樣的分隔線白对。可以達(dá)到不同條目不同分隔線的效果换怖,而不是像ListView那樣只能通過將分隔線寫進(jìn)itemView布局的方式來實現(xiàn)甩恼。
  4. ListView沒有提供方法來控制添加/刪除條目時的動畫,而RecyclerView有RecyclerView.ItemAnimator來控制條目動畫沉颂。
  5. ListView擁有AdapterView.OnItemClickListener來處理每個條目的點擊事件条摸。而RecyclerView只有RecyclerView.OnItemTouchListener來處理MotionEvent,而并沒有一個內(nèi)置的點擊事件處理铸屉。
  6. 當(dāng)列表數(shù)據(jù)發(fā)生改變時钉蒲,ListView只有一個notifyDataSetChanged()方法來刷新所有條目。而RecyclerView提供了 notifyItemChanged() 彻坛、notifyItemInserted() 顷啼、notifyItemRemoved()notifyDataSetChanged() 等方法昌屉,內(nèi)部實現(xiàn)了局部刷新钙蒙,更加高效。
    所以由上面幾點可以看出间驮,RecyclerView可以實現(xiàn)和ListView一樣的界面躬厌,但是比ListView要靈活得多,同時其內(nèi)部自動實現(xiàn)了itemView的重用蜻牢。靈活的代價意味著開發(fā)者在配置控件時需要做更多工作烤咧,RecyclerView的分隔線偏陪、點擊事件分發(fā)抢呆、條目動畫都要自己去實現(xiàn),所以本文就推薦一些好用的RecyclerView輪子笛谦。

2 萬能分隔線RecyclerView-FlexibleDivider

yqritc/RecyclerView-FlexibleDivider
框架提供了HorizontalDividerItemDecorationVerticalDividerItemDecoration分別對應(yīng)水平/豎直的divider抱虐。
通過Builder的方式構(gòu)造分隔線,你可以很方便地設(shè)置分隔線的margin饥脑、顏色恳邀、粗細(xì)甚至圖案:

recyclerView.addItemDecoration(
 new HorizontalDividerItemDecoration.Builder(this)
.color(Color.RED) 
.sizeResId(R.dimen.divider)
.marginResId(R.dimen.leftmargin, R.dimen.rightmargin) 
.build());

也可以通過實現(xiàn)各種Provider接口懦冰,來設(shè)置不同位置不同樣式的分隔線:

recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this)
.sizeProvider(new  FlexibleDividerDecoration.SizeProvider(){
   @Override
  public int dividerSize(int position, RecyclerView parent) {
    switch (position % 10) {//不同位置不同高度
      case 0:
        return 30;
      case 1:
        return 10;
      default:
        return 2+position;
      }
    }
  })
.build());
sample2.gif

3 各式各樣的ItemAnimator實現(xiàn)

gabrielemariotti/RecyclerViewItemAnimators
提供包括SlideInOutLeftItemAnimatorSlideInOutRightItemAnimator 谣沸、SlideInOutTopItemAnimator 刷钢、SlideInOutBottomItemAnimatorScaleInOutItemAnimator 在內(nèi)的各種自定義條目動畫效果的實現(xiàn)乳附。

  1. 單個條目的動畫設(shè)置:
mRecyclerView.setItemAnimator(new SlideInOutLeftItemAnimator(mRecyclerView));
  1. 整個列表的動畫設(shè)置:
mAdapter = new MyAdapter(this); 
//通過AlphaAnimatorAdapter來包裝 原來的列表adapter
AlphaAnimatorAdapter animatorAdapter = new AlphaAnimatorAdapter(mAdapter, mRecyclerView); 
mRecyclerView.setAdapter(animatorAdapter);
demo.gif

4 支持復(fù)雜的多類型列表視圖

drakeet/MultiType
項目中經(jīng)常會需要寫一個復(fù)雜的内地、多 itemView types 的列表視圖,經(jīng)常要做一堆繁瑣的工作赋除,而且不小心的話代碼還堆積嚴(yán)重:我們需要覆寫RecyclerView.AdaptergetItemViewType()方法阱缓,并新增一些 type 整形常量,而且 ViewHolder繼承举农、泛型傳遞荆针、轉(zhuǎn)型也比較糟糕。
通過這個庫可以輕松簡單地實現(xiàn)包含多種不同類型條目的列表:

  1. 列表中的數(shù)據(jù)必須實現(xiàn)Item接口
  2. 創(chuàng)建一個類繼承ItemViewProvider颁糟,里面指定了某個Item Type的布局和這個條目對應(yīng)的RecyclerView.ViewHolder航背。
  3. 在Application 中進(jìn)行注冊類型:
public class App extends Application {
 
    @Override public void onCreate() {
        super.onCreate();
        MultiTypePool.register(TextItem.class, new TextItemViewProvider());
        MultiTypePool.register(ImageItem.class, new ImageItemViewProvider());
    }
}
  1. 然后創(chuàng)建MultiTypeAdapter,將數(shù)據(jù)集合(實現(xiàn)Item接口的javaBean的集合)設(shè)置進(jìn)去即可棱貌。
 recyclerView.setAdapter(new MultiTypeAdapter(items));

十分簡單優(yōu)雅有木有沃粗?!

screenshot-normal.png

類似的還有sockeqwe/AdapterDelegates

5 點擊事件的分發(fā)

RecyclerView并沒有提供一個OnItemClickListener給開發(fā)者去處理條目的點擊事件键畴。最簡單的辦法是自己寫個回調(diào)接口最盅,然后給itemView設(shè)置onClick時去觸發(fā)這個回調(diào)接口。
RecyclerView無法添加onItemClickListener最佳的高效解決方案這篇文章通過 recyclerView.addOnItemTouchListener()和系統(tǒng)提供的 GestureDetector 手勢判斷結(jié)合實現(xiàn)的起惕∥屑總感覺把簡單的問題復(fù)雜化了。
這里有一個簡單的工具類可以方便實現(xiàn): ItemClickSupport decorator惹想,使用起來十分簡單:

ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(
        new ItemClickSupport.OnItemClickListener() {
            @Override
            public void onItemClicked(RecyclerView recyclerView, int position, View v) {
                // do something.
            }
        });

6 對Adapter的一些封裝

避免自定義Adapter時造成過多的重復(fù)代碼问词。且通過裝飾者模式優(yōu)雅地為RecyclerView添加header或者footer:
hongyangAndroid/baseAdapter
主要是在項目中使用RecyclerView.Adapter可以參考這個開源框架的一些思路,做一些優(yōu)雅的封裝嘀粱。

7 相關(guān)連接

  1. Using the RecyclerView
  2. RecyclerView 和 ListView 使用對比分析
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末激挪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子锋叨,更是在濱河造成了極大的恐慌垄分,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娃磺,死亡現(xiàn)場離奇詭異薄湿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門豺瘤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吆倦,“玉大人,你說我怎么就攤上這事坐求〔显螅” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵桥嗤,是天一觀的道長赛糟。 經(jīng)常有香客問我,道長砸逊,這世上最難降的妖魔是什么璧南? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮师逸,結(jié)果婚禮上司倚,老公的妹妹穿的比我還像新娘。我一直安慰自己篓像,他們只是感情好动知,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著员辩,像睡著了一般盒粮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奠滑,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天丹皱,我揣著相機(jī)與錄音,去河邊找鬼宋税。 笑死摊崭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的杰赛。 我是一名探鬼主播呢簸,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼乏屯!你這毒婦竟也來了根时?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤辰晕,失蹤者是張志新(化名)和其女友劉穎蛤迎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伞芹,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡忘苛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年蝉娜,在試婚紗的時候發(fā)現(xiàn)自己被綠了唱较。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扎唾。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖南缓,靈堂內(nèi)的尸體忽然破棺而出胸遇,到底是詐尸還是另有隱情,我是刑警寧澤汉形,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布纸镊,位于F島的核電站,受9級特大地震影響概疆,放射性物質(zhì)發(fā)生泄漏逗威。R本人自食惡果不足惜顺呕,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一趁舀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芥喇,春花似錦使套、人聲如沸罐呼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫉柴。三九已至,卻和暖如春奉呛,著一層夾襖步出監(jiān)牢的瞬間计螺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工瞧壮, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留危尿,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓馁痴,卻偏偏與公主長得像谊娇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子罗晕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,498評論 25 707
  • 這篇文章分三個部分济欢,簡單跟大家講一下 RecyclerView 的常用方法與奇葩用法;工作原理與ListView比...
    LucasAdam閱讀 4,377評論 0 27
  • 每天空閑時間很多小渊,做的事情太少法褥;擁有是理想太多,付出行動太少酬屉;想要擁有的太多半等,實際的能力太少揍愁;看著時間大把...
    _遇見閱讀 1,602評論 0 1