Android控件RecyclerView和ListView的異同

在我的一篇介紹Android新控件RecyclerView的博客( Android L新控件RecyclerView簡(jiǎn)介 )中慢蜓,一個(gè)讀者留言說(shuō)RecyclerView跟ListView之間好像沒(méi)有什么不同,我覺(jué)得這是一個(gè)好問(wèn)題末患,應(yīng)該明確地區(qū)分一下兩者的睯,所以我就研究了一下它倆之間的區(qū)別淑履,然后也對(duì)兩者的使用有了更加深入的了解队魏。
Android是一個(gè)不斷進(jìn)化的平臺(tái)糕伐,Android 5.0的v7版本支持包中引入了新的RecyclerView控件忍啸,正如官方文檔所言仰坦,RecyclerView是ListView的豪華增強(qiáng)版。它主要包含以下幾處新的特性计雌,如ViewHolder悄晃,ItemDecorator,LayoutManager凿滤,SmothScroller以及增加或刪除item時(shí)item動(dòng)畫等妈橄。官方推薦我們采用RecyclerView來(lái)取代ListView。
ViewHolder
ViewHolder是用來(lái)保存視圖引用的類翁脆,無(wú)論是ListView亦或是RecyclerView眷蚓。只不過(guò)在ListView中,ViewHolder需要自己來(lái)定義反番,且這只是一種推薦的使用方式溪椎,不使用當(dāng)然也可以,這不是必須的恬口。只不過(guò)不使用ViewHolder的話,ListView每次getView的時(shí)候都會(huì)調(diào)用findViewById(int)沼侣,這將導(dǎo)致ListView性能展示遲緩祖能。而在RecyclerView中使用 RecyclerView.ViewHolder 則變成了必須,盡管實(shí)現(xiàn)起來(lái)稍顯復(fù)雜蛾洛,但它卻解決了ListView面臨的上述不使用自定義ViewHolder時(shí)所面臨的問(wèn)題养铸。 RecyclerView.ViewHolder 被BaseAdapter使用,以將posiiton綁定到上面(可以通過(guò)API查看 RecyclerView.ViewHolder#getPosition() 方法)轧膘。
LayoutManager
我們知道ListView只能在垂直方向上滾動(dòng)钞螟,Android API沒(méi)有提供ListView在水平方向上面滾動(dòng)的支持』寻或許有多種方式實(shí)現(xiàn)水平滑動(dòng)鳞滨,但是請(qǐng)想念我,ListView并不是設(shè)計(jì)來(lái)做這件事情的蟆淀。但是RecyclerView相較于ListView拯啦,在滾動(dòng)上面的功能擴(kuò)展了許多。它可以支持多種類型列表的展示要求熔任,主要如下:

LinearLayoutManager 褒链,可以支持水平和豎直方向上滾動(dòng)的列表。
StaggeredGridLayoutManager 疑苔,可以支持交叉網(wǎng)格風(fēng)格的列表甫匹,類似于瀑布流或者Pinterest。
GridLayoutManager ,支持網(wǎng)格展示兵迅,可以水平或者豎直滾動(dòng)抢韭,如展示圖片的畫廊。
ItemAnimator
列表動(dòng)畫是一個(gè)全新的喷兼、擁有無(wú)限可能的維度篮绰。起初的Android API中,刪除或添加item時(shí)季惯,item是無(wú)法產(chǎn)生動(dòng)畫效果的吠各。后面隨著Android的進(jìn)化,Google的Chat Hasse推薦使用 ViewPropertyAnimator 屬性動(dòng)畫來(lái)實(shí)現(xiàn)上述需求勉抓。
相比較于ListView贾漏, RecyclerView.ItemAnimator 則被提供用于在RecyclerView添加、刪除或移動(dòng)item時(shí)處理動(dòng)畫效果藕筋。同時(shí)纵散,如果你比較懶,不想自定義ItemAnimator隐圾,你還可以使用 DefaultItemAnimator 伍掀。
Adapter
ListView的Adapter中,getView是最重要的方法暇藏,它將視圖跟position綁定起來(lái)蜜笤,是所有神奇的事情發(fā)生的地方。同時(shí)我們也能夠通過(guò)registerDataObserver在Adapter中注冊(cè)一個(gè)觀察者盐碱。RecyclerView也有這個(gè)特性把兔, RecyclerView.AdapterDataObserver 就是這個(gè)觀察者。ListView有三個(gè)Adapter的默認(rèn)實(shí)現(xiàn)瓮顽,分別是ArrayAdapter县好、CursorAdapter和SimpleCursorAdapter。然而暖混,RecyclerView的Adapter則擁有除了內(nèi)置的內(nèi)DB游標(biāo)和ArrayList的支持之外的所有功能缕贡。 RecyclerView.Adapter 的實(shí)現(xiàn)的,我們必須采取措施將數(shù)據(jù)提供給Adapter儒恋,正如BaseAdapter對(duì)ListView所做的那樣善绎。
ItemDecoration
在ListView中如果我們想要在item之間添加間隔符,我們只需要在布局文件中對(duì)ListView添加如下屬性即可:

 1 android:divider="@android:color/transparent"
 2 android:dividerHeight="5dp"

View Code
有趣的是诫尽,RecyclerView在默認(rèn)情況下并不在item之間展示間隔符禀酱。盡管Google的家伙有意地將這個(gè)問(wèn)題遺留給我們?nèi)プ远x間隔符,但這的確增加了開(kāi)發(fā)人員的負(fù)擔(dān)牧嫉。如果你想要添加間隔符剂跟,你必須使用RecyclerView.ItemDecoration類來(lái)實(shí)現(xiàn)减途。或者曹洽,你可以應(yīng)用官方示例中的 DividerItemDecoration.java 文件鳍置。
OnItemTouchListener
ListView通過(guò)AdapterView.OnItemClickListener接口來(lái)探測(cè)點(diǎn)擊事件。而RecyclerView則通過(guò)RecyclerView.OnItemTouchListener接口來(lái)探測(cè)觸摸事件送淆。它雖然增加了實(shí)現(xiàn)的難度税产,但是卻給予開(kāi)發(fā)人員攔截觸摸事件更多的控制權(quán)限。
Others
ListView可以設(shè)置選擇模式偷崩,并添加MultiChoiceModeListener辟拷,如下所示:

1 listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
 2 listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
 3     public boolean onCreateActionMode(ActionMode mode, Menu menu) { ... }
 4     public void onItemCheckedStateChanged(ActionMode mode, int position,
 5 long id, boolean checked) { ... }
 6     public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
 7         switch (item.getItemId()) {
 8             case R.id.menu_item_delete_crime:
 9             CrimeAdapter adapter = (CrimeAdapter)getListAdapter();
10             CrimeLab crimeLab = CrimeLab.get(getActivity());
11             for (int i = adapter.getCount() - 1; i >= 0; i--) {
12                 if (getListView().isItemChecked(i)) {
13                     crimeLab.deleteCrime(adapter.getItem(i));
14                 }
15           }
16         mode.finish();
17         adapter.notifyDataSetChanged();
18         return true;
19         default:
20             return false;
21 }
22     public boolean onPrepareActionMode(ActionMode mode, Menu menu) { ... }
23     public void onDestroyActionMode(ActionMode mode) { ... }
24 });

View Code
而RecyclerView則沒(méi)有此功能。
總之阐斜,通過(guò)比較我們可以發(fā)現(xiàn)衫冻,RecyclerView充滿了大量的自定義功能,它可以用于實(shí)現(xiàn)復(fù)雜的列表或網(wǎng)格谒出,但實(shí)現(xiàn)起來(lái)稍顯得復(fù)雜隅俘。
博客書寫過(guò)程中參考內(nèi)容有:
Android RecyclerView vs ListView|Comparision
RecyclerView Part 1:Fundamentals For ListView Experts
RecyclerView Part 2:Choice Modes

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市笤喳,隨后出現(xiàn)的幾起案子为居,更是在濱河造成了極大的恐慌,老刑警劉巖杀狡,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颜骤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡捣卤,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門八孝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)董朝,“玉大人,你說(shuō)我怎么就攤上這事干跛∽咏” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵楼入,是天一觀的道長(zhǎng)哥捕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)嘉熊,這世上最難降的妖魔是什么遥赚? 我笑而不...
    開(kāi)封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮阐肤,結(jié)果婚禮上凫佛,老公的妹妹穿的比我還像新娘讲坎。我一直安慰自己,他們只是感情好愧薛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布晨炕。 她就那樣靜靜地躺著,像睡著了一般毫炉。 火紅的嫁衣襯著肌膚如雪瓮栗。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天瞄勾,我揣著相機(jī)與錄音费奸,去河邊找鬼。 笑死丰榴,一個(gè)胖子當(dāng)著我的面吹牛货邓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播四濒,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼换况,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了盗蟆?” 一聲冷哼從身側(cè)響起戈二,我...
    開(kāi)封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喳资,沒(méi)想到半個(gè)月后觉吭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仆邓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年鲜滩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片节值。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡徙硅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出搞疗,到底是詐尸還是另有隱情嗓蘑,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布匿乃,位于F島的核電站桩皿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏幢炸。R本人自食惡果不足惜泄隔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宛徊。 院中可真熱鬧梅尤,春花似錦柜思、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至缰揪,卻和暖如春陨享,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钝腺。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工抛姑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人艳狐。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓定硝,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親毫目。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蔬啡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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