RecyclerView是ListView的增強版。有了它之后,你就可以拋棄ListView了。
recycle,重復利用。在ListView里,我們得自己寫重復利用View的代碼,而RecyclerView則是將此內置進去,并提供清晰的結構。
設計模式相關
RecyclerView 和 ListView 都是使用對象適配器模式。我專門為此寫了一篇對適配器模式的介紹:設計模式:適配器模式
以下是該模式的UML類圖(方便起見,為箭頭加了說明):
對應到 RecyclerView :
類圖 | RecyclerView |
---|---|
Client | android.support.v7.widget.RecyclerView |
Target | android.support.v7.widget.RecyclerView.Adapter<VH extends android.support.v7.widget.RecyclerView.ViewHolder> |
Adapter | 自己繼承RecyclerView.Adapter并實現 |
Adaptee | 需要展示的List數據 |
這里RecyclerView的Target沒有再提出接口,直接寫成抽象類
遠程依賴庫
如果使用RecyclerView,則需要在build.gradle的dependencies里添加遠程依賴庫:
compile 'com.android.support:recyclerview-v7:25.1.0'
這是為了讓低版本的Android系統可以用到這個RecyclerView。如果不這樣,則低版本無法使用。
RecyclerView 和 ListView 有什么不同?
- 繼承結構不同:
- 它自帶ViewHolder。我們再也不必自己添加各種判斷了。
- 行布局文件不再由外部傳入,而是在內部的onCreateViewHolder()里直接使用。
- 添加了橫向的支持,即左右滾動。這個可以用在Android TV上。
- ……
RecyclerView的Adapter(以下稱為RecyclerViewAdapter)內部需要重寫的幾個部分:
通過構造方法獲得List
ListViewAdapter也是通過構造方法獲得List,但還有另外兩個參數,分別是Context和行布局的resourceId。
通過onCreateViewHolder()加載布局
ListViewAdapter在getView()里加載。
通過創建內部類并繼承RecyclerView.ViewHolder來獲取布局里的控件
ListViewAdapter也是創建內部類,但它是把findViewById()放到getView()里。RecyclerViewAdapter則是放在這個內部類里面。
通過onBindViewHolder()給控件賦值
Bind即綁定,意思是把數據綁定到ViewHolder上。
ListViewAdapter把這個動作放在getView()里。
從這幾個部分可以看到,本來getView()里做的三個動作,現在分到三個不同的地方。
如下圖,左邊是ListView的Adapter,右邊是RecyclerView的Adapter:
除此之外,RecyclerView需要在初始化它的地方給它傳入LayoutManager。
如下圖,左邊是ListView的Activity,右邊是RecyclerView的Activity:
ListView 自帶三種Adapter的實現。例如很常用的ArrayAdapter,而RecyclerView則沒有這樣的實現,必須自己寫Adapter并重寫上面所說的各個方法。
雖然RecyclerView的Adapter沒有ListView的三種方便的實現,但它有三個子類:
- ItemBridgeAdapter
- LeanbackListPreferenceDialogFragment.AdapterMulti
- LeanbackListPreferenceDialogFragment.AdapterSingle
這三個是給媒體設備(電視)或者游戲用的。所以如果你想要ArrayAdapter<T>
;SimpleAdapter
;SimpleCursorAdapter
的效果,你得通過繼承RecyclerView.Adapter來自己實現。
這里有個RecyclerView對SimpleCursorAdapter
的實現:CursorRecyclerAdapter.java
效果
左邊是ListView,右邊是RecyclerView:
RecyclerView默認沒有分割線。
如果想要分割線,可以使用默認的DividerItemDecoration:
DividerItemDecoration divider =
new DividerItemDecoration(recyclerView.getContext(),
layoutManager.getOrientation());
recyclerView.addItemDecoration(divider);
也可以通過繼承RecyclerView.ItemDecoration來自定義。
點擊事件
由于每一個Item里面可能有多個視圖,如果想直接點擊這些視圖,在ListView里實現比較麻煩。
與ListView的setOnItemClickListener()不同,RecyclerView需要在其Adapter的onCreateViewHolder()里設置點擊事件。
文章列表