真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

RecyclerView的布局原理及四級緩存-創(chuàng)新互聯(lián)

在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。ArrayListmAttachedScrap; 保存的是屏幕上沒有任何變化的ViewHolder,?ArrayListmChangedScrap保存的是有變化ViewHolder,比如刷新了某個item那個此ViewHolder會被保存到mChangedScrap中

2:第二級緩存,不需要重新bindViewHolder,需要進行位置一致性校驗,隨著列表的上下滑動,被劃出屏幕的ViewHolder就會儲存到這里;可通過setItemCacheSize調(diào)整,默認(rèn)大小為2;ArrayListmCacheViews;

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)查看詳情吧


當(dāng)前題目:RecyclerView的布局原理及四級緩存-創(chuàng)新互聯(lián)
文章來源:http://weahome.cn/article/ddiccg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部