在Android應(yīng)用開發(fā)過程中,只要是涉及到列表類的數(shù)據(jù)加載,RecyclerView的使用都是必不可少的。那么RecyclerView有哪些值得我們借鑒的地方呢?讓我們來一探究竟。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:主機域名、網(wǎng)站空間、營銷軟件、網(wǎng)站建設(shè)、玉環(huán)網(wǎng)站維護、網(wǎng)站推廣。一、測量和布局: RecyclerView測繪布局有三步,分別為start,layout和animation。對應(yīng)的方法為dispatchLayoutStep1()、dispatchLayoutStep2()、dispatchLayoutStep3()。?具體看源碼,首先,我們先進行開始測繪布局前的準(zhǔn)備工作,從recyclerView的setLayoutManager開始,從這里可以看出主要做了兩件事情,一是判斷當(dāng)前的RecyclerView有無依賴的LayoutManager,如果有就清除掉。二是判斷當(dāng)前的LayoutManager是否依賴在了其他的RecyclerView上,如果有就直接拋出異常
if (mLayout != null) {
mRecycler.clear();
if (mIsAttached) { //移除依賴
mLayout.dispatchDetachedFromWindow(this, mRecycler);
}
mLayout.setRecyclerView(null);
mLayout = null;
}else{
mRecycler.clear();
}
if (layout != null) {
if (layout.mRecyclerView != null) {
throw new IllegalArgumentException("LayoutManager " + layout
+ " is already attached to a RecyclerView:"
+ layout.mRecyclerView.exceptionLabel());
}
mLayout.setRecyclerView(this);
if (mIsAttached) {
mLayout.dispatchAttachedToWindow(this);
}
}
緊接著,由于RecyclerView繼承的是ViewGroup,所以他的測繪布局動作也是我們重要看的。首先看onMeasure()測量方法。這里主要做了2件事情,
1:在某些極端情況下計算出盡可能合理的寬高值,進行兜底的操作
2:開啟測量,布局的階段,主要是dispatchLayoutStep2方法。此方法里面主要進行了item的布局工作,其中,至關(guān)重要的一個方法是執(zhí)行了RecyclerView的onLayoutChildren方法,LinearLayoutManager,GridLayoutManager等布局管理器會實現(xiàn)此方法,進行具體的布局邏輯
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
//1:layoutManager 若為空,則無法進行測量,這時候會通過默認(rèn)方法,盡可能的給出準(zhǔn)確的尺寸
if (mLayout == null) {
defaultOnMeasure(widthSpec, heightSpec);
return;
}
//開啟自動測量
if (mLayout.isAutoMeasureEnabled()) {
final int widthMode = MeasureSpec.getMode(widthSpec);
final int heightMode = MeasureSpec.getMode(heightSpec);
mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
final boolean measureSpecModeIsExactly =
widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY;
if (measureSpecModeIsExactly || mAdapter == null) {
return;
}
//這里主要對需要做動畫的item進行收集和整理,完成后會把mState.mLayoutStep賦值成
//STEP_LAYOUT
if (mState.mLayoutStep == State.STEP_START) {
dispatchLayoutStep1();
}
//開始測量,并布局列表上的item,從而期望能夠計算出RecyclerView的寬高
dispatchLayoutStep2();
//如果RecyclerView沒有準(zhǔn)確的寬高,并且至少有一個item也沒有固定的寬高,則對再走一
//遍。 dispatchLayoutStep2(),進行更加準(zhǔn)確的測量,從而能夠得出RecyclerView的寬
//高。從這里我們也可以看出,在實際開發(fā)過程中盡肯能的對RecyclerView的寬高設(shè)置為精確
//的值。這里這行完成后,狀態(tài)會被賦值成STEP_ANIMATIONS,開始第3階段
if (mLayout.shouldMeasureTwice()) {
mLayout.setMeasureSpecs(
MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
mState.mIsMeasuring = true;
dispatchLayoutStep2();
// now we can get the width and height from the children.
mLayout.setMeasuredDimensionFromChildren(widthSpec, heightSpec);
}
}
}
最后,測量完成結(jié)束,會走到onLayout()回調(diào)中,如果前面沒有開啟自動測量,這里會再重新走一次dispatchLayoutStep1和2,再執(zhí)行dispatchLayoutStep3,dispatchLayoutStep3里主要進行了動畫執(zhí)行的邏輯。
// onLayout的dispatchLayout()方法
void dispatchLayout() {
if (mState.mLayoutStep == State.STEP_START) {
dispatchLayoutStep1();
mLayout.setExactMeasureSpecsFrom(this);
dispatchLayoutStep2();
} else if (mAdapterHelper.hasUpdates() || mLayout.getWidth() != getWidth()
|| mLayout.getHeight() != getHeight()) {
// First 2 steps are done in onMeasure but looks like we have to run
//again due to
// changed size.
mLayout.setExactMeasureSpecsFrom(this);
dispatchLayoutStep2();
} else {
// always make sure we sync them (to ensure mode is exact)
mLayout.setExactMeasureSpecsFrom(this);
}
dispatchLayoutStep3();
}
二、四級緩存1:第一級緩存,不需要重新bindViewHolder。ArrayList
2:第二級緩存,不需要重新bindViewHolder,需要進行位置一致性校驗,隨著列表的上下滑動,被劃出屏幕的ViewHolder就會儲存到這里;可通過setItemCacheSize調(diào)整,默認(rèn)大小為2;ArrayList
3:自定義拓展View緩存,ViewCacheExtension mViewCacheExtension;可忽略
4:第四級緩存,當(dāng)且僅當(dāng)mCacheViews放不下的時候,會放入這個緩存里。根據(jù)viewType存取ViewHolder,可通過setRecycledViewPool調(diào)整,每個類型容量默認(rèn)為5;RecycledViewPool mRecyclerPool;
三、復(fù)用機制LayoutManager每次向列表上填充item的時候,會向Recycler索取ViewHolder優(yōu)先級非別為mAttachScrp和mChangedScrp(屏幕內(nèi)的ViewHolder,不需要重新綁定數(shù)據(jù)),mCacheViews(滑出屏幕的ViewHolder,也是不需要重新進行數(shù)據(jù)綁定,需要進行位置一致性校驗,判斷滑出屏幕的ViewHolder是否和需要現(xiàn)在重新放置的ViewHolder位置一致)和mRecyclerPool(需要重新進行數(shù)據(jù)綁定)。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧