1. 程式人生 > >android技術-----ListView和RecyclerView

android技術-----ListView和RecyclerView

一、RecyclerView在很多方面能取代ListView,Google為什麼沒把ListView劃上一條過時的橫線?
ListView採用的是RecyclerBin的回收機制在一些輕量級的List顯示時效率更高。

RecyclerView 與 ListView 的主要區別:
1、佈局效果對比
2、常用功能與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() 用來處理Adapter中資料為空的情況;但是在RecyclerView中沒有這個API,所以在RecyclerView中需要進行一些資料判斷來實現資料為空的情況;

四、HeaderView 與 FooterView:
ListView中可以通過addHeaderView() 與 addFooterView()來新增頭部item與底部item,來當我們需要實現下拉重新整理或者上拉載入的情況;而且這兩個API不會影響Adapter的編寫;
但是RecyclerView中並沒有這兩個API,所以當我們需要在RecyclerView新增頭部item或者底部item的時候,我們可以在Adapter中自己編寫,根據ViewHolder的Type與View來實現自己的Header,Footter與普通的item,但是這樣就會影響到Adapter的資料,比如position,添加了Header與Footter後,實際的position將大於資料的position;

五、區域性重新整理
在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某個操作方法;

9、巢狀滾動機制:
在事件分發機制中,Touch事件在進行分發的時候,由父View向子View傳遞,一旦子View消費這個事件的話,那麼接下來的事件分發的時候,父View將不接受,由子View進行處理;但是與Android的事件分發機制不同,巢狀滾動機制(Nested Scrolling)可以彌補這個不足,能讓子View與父View同時處理這個Touch事件,主要實現在於NestedScrollingChild與NestedScrollingParent這兩個介面;而在RecyclerView中,實現的是NestedScrollingChild,所以能實現巢狀滾動機制;
ListView就沒有實現巢狀滾動機制;

十、設定分割

 在ListView中如果我們想要在item之間新增間隔符,我們只需要在佈局檔案中對ListView新增如下屬性即可:

    android:divider="@android:color/transparent"
    android:dividerHeight="5dp"

 

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


原文:https://blog.csdn.net/shu_lance/article/details/79566189