ListView與RecyclerView的區別

RecyclerView 與 ListView 的主要區別:

  1. 佈局效果對比
  2. 常用功能與API對比
  3. 在Android L引入嵌套滾動機制(NestedScrolling)
  4. 緩存機制
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工作,但實現了佈局效果多樣化;

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

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

HeaderView 與 FooterView:
  1. 在ListView中可以通過addHeaderView()addFooterView()來添加頭部item與底部item,來當我們需要實現下拉刷新或者上拉加載的情況;而且這兩個API不會影響Adapter的編寫;
  2. 但是RecyclerView中並沒有這兩個API,所以當我們需要在RecyclerView添加頭部item或者底部item的時候,我們可以在Adapter中自己編寫,根據ViewHolder的Type與View來實現自己的Header,Footter與普通的item,但是這樣就會影響到Adapter的數據,比如position,添加了Header與Footter後,實際的position將大於數據的position;
局部刷新
  1. 在ListView中通常刷新數據是用notifyDataSetChanged() ,但是這種刷新數據是全局刷新的(每個item的數據都會重新加載一遍),這樣一來就會非常消耗資源;
  2. RecyclerView中可以實現局部刷新,例如:notifyItemChanged();
  3. 但是如果要在ListView實現局部刷新,依然是可以實現的,當一個item數據刷新時,我們可以在Adapter中,實現一個onItemChanged()方法,在方法裏面獲取到這個item的position(可以通過getFirstVisiblePosition()),然後調用getView()方法來刷新這個item的數據;
動畫效果:
  1. 在RecyclerView中,已經封裝好API來實現自己的動畫效果;有許多動畫API,例如:notifyItemChanged(), notifyDataInserted(), notifyItemMoved()等等;如果我們需要淑賢自己的動畫效果,我們可以通過相應的接口實現自定義的動畫效果(RecyclerView.ItemAnimator類),然後調用RecyclerView.setItemAnimator() (默認的有SimpleItemAnimator與DefaultItemAnimator);
  2. 但是ListView並沒有實現動畫效果,但我們可以在Adapter自己實現item的動畫效果;
ItemTouchHelper:
  1. 創建ItemTouchHelper實例,然後在ItemTouchHelper.SimpleCallback(),然後在Callback中實現getMovementFlags(), onMove(), onSwiped(), 最後調用RecyclerView的attachToRecyclerView方法;
Item點擊事件:
  1. 在ListView中有onItemClickListener(), onItemLongClickListener(), onItemSelectedListener(), 但是添加HeaderView與FooterView後就不一樣了,因爲HeaderView與FooterView都會算進position中,這時會發現position會出現變化,可能會拋出數組越界,爲了解決這個問題,我們在getItemId()方法(在該方法中HeaderView與FooterView返回的值是-1)中通過返回id來標誌對應的item,而不是通過position來標記;但是我們可以在Adapter中針對每個item寫在getView()中會比較合適;
  2. 而在RecyclerView中,提供了唯一一個API:addOnItemTouchListener(),監聽item的觸摸事件;我們可以通過RecyclerView的addOnItemTouchListener()加上系統提供的Gesture Detector來實現像ListView那樣監聽某個item某個操作方法;
嵌套滾動機制:
  1. 在事件分發機制中,Touch事件在進行分發的時候,由父View向子View傳遞,一旦子View消費這個事件的話,那麼接下來的事件分發的時候,父View將不接受,由子View進行處理;但是與Android的事件分發機制不同,嵌套滾動機制(Nested Scrolling)可以彌補這個不足,能讓子View與父View同時處理這個Touch事件,主要實現在於NestedScrollingChildNestedScrollingParent這兩個接口;而在RecyclerView中,實現的是NestedScrollingChild,所以能實現嵌套滾動機制;
  2. ListView就沒有實現嵌套滾動機制;

緩存機制:

RecyclerView比ListView多兩級緩存,支持多個離ItemView緩存,支持開發者自定義緩存處理邏輯,支持所有RecyclerView共用同一個RecyclerViewPool(緩存池)。
  1. RecyclerView(四級緩存)比ListView多兩級緩存(兩級緩存),支持多個ItemView緩存,支持開發者自定義緩存處理邏輯,支持所有RecyclerView共用同一個RecyclerViewPool(緩存池);
  2. RecyclerView緩存RecyclerView.ViewHolder,抽象理解爲:View + ViewHolder(避免每次createView時調用findViewById) + flag(標識狀態),ListView緩存View;
總結:

這裏只是客觀的分析ListView與RecyclerView的差異,而在實際場景中,我們應該根據自己的需求來選擇使用RecyclerView還是ListView,畢竟,適合業務需求的纔是最好的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章