一、兩者的緩存機制上的區(qū)別
先來說一樣的地方,ListView與RecyclerView緩存機制原理大致一樣,滑動的時候,離開屏幕的ItemView被回收到緩存,新的itemView加在優(yōu)先獲取的緩存中的,這是正常的兩種類似的緩存機制。
而不同的地方在于,兩者的緩存層級不同,ListView只有兩層,RecycleView有四級緩存。
1. mActiveViews和mAttachedScrap功能相似,意義在于快速重用屏幕上可見的列表項ItemView,而不需要重新createView和bindView;
2. mScrapView和mCachedViews + mReyclerViewPool功能相似,意義在于緩存離開屏幕的ItemView,目的是讓即將進入屏幕的ItemView重用;
3. RecyclerView的優(yōu)勢在于: a.mCacheViews的使用,可以做到屏幕外的列表項ItemView進入屏幕內(nèi)時也無須bindView快速重用; b.mRecyclerPool可以供多個RecyclerView共同使用,在特定場景下,如viewpaper+多個列表頁下有優(yōu)勢.客觀來說,RecyclerView在特定場景下對ListView的緩存機制做了補強和完善。
同時,兩者的緩存不同,RecycleView緩存在ViewHolder,可以看作是:View + ViewHolder(避免每次createView時調(diào)用findViewById) + flag(標(biāo)識狀態(tài));而ListView緩存在View上,獲取緩存的方法流程是:

listView的mScrapViews是根據(jù)pos獲取相應(yīng)的緩存,但不直接用,是重新getView(這樣會重新bindView)。所以ListView中通過pos獲取的是View。
RecycleView的流程是:

mRecycleView在獲取緩存的時候,是通過匹配pos獲得目標(biāo)的位置的緩存,這么做可以不用重新bindView,所以RecycleVIew中通過pos獲取的是viewholder,是pos-->(view,holder,flag),flag是判斷view是否需要重新bindView。
二、局部刷新的區(qū)別
RecycleView中的notifyItemRemoved(position)方法,最終會調(diào)用requestLayout()方法,使整個View重新繪制,為:onMeasure()-->onLayout()-->onDraw()
其中的onLayout分三步:
1.dispathLayoutStep1():記錄RecyclerView刷新前列表項ItemView的各種信息,如Top,Left,Bottom,Right,用于動畫的相關(guān)計算;
2.dispathLayoutStep2():真正測量布局大小,位置,核心函數(shù)為layoutChildren();
3.dispathLayoutStep3():計算布局前后各個ItemView的狀態(tài),如Remove,Add,Move,Update等,如有必要執(zhí)行相應(yīng)的動畫.
其中l(wèi)ayoutChildren()方法的流程圖:


當(dāng)調(diào)用notifyItemRemoved時,會對屏幕內(nèi)ItemView做預(yù)處理,修改ItemView相應(yīng)的pos以及flag。當(dāng)調(diào)用fill()中RecyclerView.getViewForPosition(pos)時,RecyclerView通過對pos和flag的預(yù)處理,使得bindview只調(diào)用一次。
需要指出,ListView和RecyclerView最大的區(qū)別在于數(shù)據(jù)源改變時的緩存的處理邏輯,ListView是"一鍋端",將所有的mActiveViews都移入了二級緩存mScrapViews,而RecyclerView則是更加靈活地對每個View修改標(biāo)志位,區(qū)分是否重新bindView。
以上
新聞熱點
疑難解答