ListView 與 RecyclerView 簡單對比
阿新 • • 發佈:2019-01-31
RecyclerView 與 ListView 的主要區別:
- 佈局效果對比
- 常用功能與API對比
- 在Android L引入巢狀滾動機制(NestedScrolling)
ListView與RecyclerView的簡單使用:
ListView:
1. 繼承重寫BaseAdapter類;
2. 自定義ViewHolder與convertView的優化(判斷是否為null);
RecyclerView:
1. 繼承重寫RecyclerView.Adapter與RecyclerView.ViewHolder
2. 設定LayoutManager,以及layout的佈局效果
區別:
1. ViewHolder的編寫規範化,ListView是需要自己定義的,而RecyclerView是規範好的;
2. RecyclerView複用item全部搞定,不需要想ListView那樣setTag()與getTag();
3. RecyclerView多了一些LayoutManager工作,但實現了佈局效果多樣化;
佈局效果:
- ListView 的佈局比較單一,只有一個縱向效果;
- RecyclerView 的佈局效果豐富, 可以在LayoutMananger中設定:線性佈局(縱向,橫向),表格佈局,瀑布流佈局
- 在RecyclerView 中,如果存在的LayoutManager不能滿足需求,可以在LayoutManager的API中自定義Layout:
例如:scrollToPosition(), setOrientation(), getOrientation(), findViewByPosition()等等;
空資料處理:
在ListView中有個setEmptyView()
HeaderView 與 FooterView:
- 在ListView中可以通過addHeaderView() 與 addFooterView()來新增頭部item與底部item,來當我們需要實現下拉重新整理或者上拉載入的情況;而且這兩個API不會影響Adapter的編寫;
- 但是RecyclerView中並沒有這兩個API,所以當我們需要在RecyclerView新增頭部item或者底部item的時候,我們可以在Adapter中自己編寫
區域性重新整理
- 在ListView中通常重新整理資料是用notifyDataSetChanged() ,但是這種重新整理資料是全域性重新整理的(每個item的資料都會重新載入一遍),這樣一來就會非常消耗資源;
- RecyclerView中可以實現區域性重新整理,例如:notifyItemChanged();
- 但是如果要在ListView實現區域性重新整理,依然是可以實現的,當一個item資料重新整理時,我們可以在Adapter中,實現一個onItemChanged()方法,在方法裡面獲取到這個item的position(可以通過getFirstVisiblePosition()),然後呼叫getView()方法來重新整理這個item的資料;
動畫效果:
- 在RecyclerView中,已經封裝好API來實現自己的動畫效果;有許多動畫API,例如:notifyItemChanged(), notifyDataInserted(), notifyItemMoved()等等;如果我們需要淑賢自己的動畫效果,我們可以通過相應的介面實現自定義的動畫效果(RecyclerView.ItemAnimator類),然後呼叫RecyclerView.setItemAnimator() (預設的有SimpleItemAnimator與DefaultItemAnimator);
- 但是ListView並沒有實現動畫效果,但我們可以在Adapter自己實現item的動畫效果;
ItemTouchHelper:
- 建立ItemTouchHelper例項,然後在ItemTouchHelper.SimpleCallback(),然後在Callback中實現getMovementFlags(), onMove(), onSwiped(), 最後呼叫RecyclerView的attachToRecyclerView方法;
Item點選事件:
- 在ListView中有onItemClickListener(), onItemLongClickListener(), onItemSelectedListener(), 但是新增HeaderView與FooterView後就不一樣了,因為HeaderView與FooterView都會算進position中,這時會發現position會出現變化,可能會丟擲陣列越界,為了解決這個問題,我們在getItemId()方法(在該方法中HeaderView與FooterView返回的值是-1)中通過返回id來標誌對應的item,而不是通過position來標記;但是我們可以在Adapter中針對每個item寫在getView()中會比較合適;
- 而在RecyclerView中,提供了唯一一個API:addOnItemTouchListener(),監聽item的觸控事件;我們可以通過RecyclerView的addOnItemTouchListener()加上系統提供的Gesture Detector來實現像ListView那樣監聽某個item某個操作方法;
巢狀滾動機制:
- 在事件分發機制中,Touch事件在進行分發的時候,由父View向子View傳遞,一旦子View消費這個事件的話,那麼接下來的事件分發的時候,父View將不接受,由子View進行處理;但是與Android的事件分發機制不同,巢狀滾動機制(Nested Scrolling)可以彌補這個不足,能讓子View與父View同時處理這個Touch事件,主要實現在於NestedScrollingChild與NestedScrollingParent這兩個介面;而在RecyclerView中,實現的是NestedScrollingChild,所以能實現巢狀滾動機制;
- ListView就沒有實現巢狀滾動機制;
總結:
這裡只是客觀的分析ListView與RecyclerView的差異,而在實際場景中,我們應該根據自己的需求來選擇使用RecyclerView還是ListView,畢竟,適合業務需求的才是最好的。