在我的一篇介紹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