ListView和RecyclerView的區(qū)別

在搞懂這個問題之前,我們最好先搞明白ListView和RecyclerView的實現(xiàn)原理,這里推薦兩篇文章:

  1. 郭霖的《Android ListView工作原理完全解析》
  2. 曾志剛的《RecyclerView剖析》

那么,ListView和RecyclerView的主要區(qū)別有哪些呢?

一、緩存機制的不同

這里可以參考《Android ListView 與 RecyclerView 對比淺析—緩存機制》

二、布局效果、常用功能與API等

參考《ListView 與 RecyclerView 簡單對比》

使用上

ListView

  1. 繼承重寫B(tài)aseAdapter類;
  2. 自定義ViewHolder與convertView的優(yōu)化;

RecyclerView

  1. 繼承重寫RecyclerView.Adapter與RecyclerView.ViewHolder
  2. 設(shè)置LayoutManager,以及l(fā)ayout的布局效果

區(qū)別:

  1. ViewHolder的編寫規(guī)范化,ListView是需要自己定義的,而RecyclerView是規(guī)范好的;
  2. RecyclerView復(fù)用item全部搞定,不需要像ListView那樣setTag()與getTag();
  3. RecyclerView多了一些LayoutManager工作,但實現(xiàn)了布局效果多樣化;

布局效果

  • ListView 的布局比較單一,只有一個縱向效果;
  • RecyclerView 的布局效果豐富, 可以在LayoutMananger中設(shè)置:線性布局(縱向,橫向),表格布局,瀑布流布局
  • 在RecyclerView 中,如果存在的LayoutManager不能滿足需求,可以在LayoutManager的API中自定義Layout:
    例如:scrollToPosition(), setOrientation(), getOrientation(), findViewByPosition()等等;

空數(shù)據(jù)處理

在ListView中有個setEmptyView() 用來處理Adapter中數(shù)據(jù)為空的情況;但是在RecyclerView中沒有這個API,所以在RecyclerView中需要進行一些數(shù)據(jù)判斷來實現(xiàn)數(shù)據(jù)為空的情況;

HeaderView 與 FooterView

  • 在ListView中可以通過addHeaderView() 與 addFooterView()來添加頭部item與底部item,來當(dāng)我們需要實現(xiàn)下拉刷新或者上拉加載的情況;而且這兩個API不會影響Adapter的編寫;
  • 但是RecyclerView中并沒有這兩個API,所以當(dāng)我們需要在RecyclerView添加頭部item或者底部item的時候,我們可以在Adapter中自己編寫,根據(jù)ViewHolder的Type與View來實現(xiàn)自己的Header,F(xiàn)ootter與普通的item,但是這樣就會影響到Adapter的數(shù)據(jù),比如position,添加了Header與Footter后,實際的position將大于數(shù)據(jù)的position;

局部刷新

  • 在ListView中通常刷新數(shù)據(jù)是用notifyDataSetChanged() ,但是這種刷新數(shù)據(jù)是全局刷新的(每個item的數(shù)據(jù)都會重新加載一遍),這樣一來就會非常消耗資源;
  • RecyclerView中可以實現(xiàn)局部刷新,例如:notifyItemChanged();
  • 但是如果要在ListView實現(xiàn)局部刷新,依然是可以實現(xiàn)的,當(dāng)一個item數(shù)據(jù)刷新時,我們可以在Adapter中,實現(xiàn)一個onItemChanged()方法,在方法里面獲取到這個item的position(可以通過getFirstVisiblePosition()),然后調(diào)用getView()方法來刷新這個item的數(shù)據(jù);

動畫效果:

  • 在RecyclerView中,已經(jīng)封裝好API來實現(xiàn)自己的動畫效果;有許多動畫API,例如:notifyItemChanged(), notifyDataInserted(), notifyItemMoved()等等;如果我們需要淑賢自己的動畫效果,我們可以通過相應(yīng)的接口實現(xiàn)自定義的動畫效果(RecyclerView.ItemAnimator類),然后調(diào)用RecyclerView.setItemAnimator() (默認(rèn)的有SimpleItemAnimator與DefaultItemAnimator);
  • 但是ListView并沒有實現(xiàn)動畫效果,但我們可以在Adapter自己實現(xiàn)item的動畫效果;

ItemTouchHelper:

  • 創(chuàng)建ItemTouchHelper實例,然后在ItemTouchHelper.SimpleCallback(),然后在Callback中實現(xiàn)getMovementFlags(), onMove(), onSwiped(), 最后調(diào)用RecyclerView的attachToRecyclerView方法;

Item點擊事件:

  • 在ListView中有onItemClickListener(), onItemLongClickListener(), onItemSelectedListener(), 但是添加HeaderView與FooterView后就不一樣了,因為HeaderView與FooterView都會算進position中,這時會發(fā)現(xiàn)position會出現(xiàn)變化,可能會拋出數(shù)組越界,為了解決這個問題,我們在getItemId()方法(在該方法中HeaderView與FooterView返回的值是-1)中通過返回id來標(biāo)志對應(yīng)的item,而不是通過position來標(biāo)記;但是我們可以在Adapter中針對每個item寫在getView()中會比較合適;
  • 而在RecyclerView中,提供了唯一一個API:addOnItemTouchListener(),監(jiān)聽item的觸摸事件;我們可以通過RecyclerView的addOnItemTouchListener()加上系統(tǒng)提供的Gesture Detector來實現(xiàn)像ListView那樣監(jiān)聽某個item某個操作方法;

嵌套滾動機制:

  • 在事件分發(fā)機制中,Touch事件在進行分發(fā)的時候,由父View向子View傳遞,一旦子View消費這個事件的話,那么接下來的事件分發(fā)的時候,父View將不接受,由子View進行處理;但是與Android的事件分發(fā)機制不同,嵌套滾動機制(Nested Scrolling)可以彌補這個不足,能讓子View與父View同時處理這個Touch事件,主要實現(xiàn)在于NestedScrollingChild與NestedScrollingParent這兩個接口;而在RecyclerView中,實現(xiàn)的是NestedScrollingChild,所以能實現(xiàn)嵌套滾動機制;
  • ListView就沒有實現(xiàn)嵌套滾動機制;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容