溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

安卓Adapter去item重復(fù)使用的方案!

發(fā)布時(shí)間:2020-06-24 16:39:39 來源:網(wǎng)絡(luò) 閱讀:2243 作者:獨(dú)行瞎 欄目:移動開發(fā)

關(guān)于adapter去重復(fù)的問題其實(shí)是個(gè)很簡單的問題,很多人沒有理解到list,grid以及recyclerview重復(fù)利用item以及使用viewholder的原理,所以在去重的道路上走得很坎坷,在這里小羽帶著大家去好好的學(xué)習(xí)和總結(jié)一下item的知識,然后使用十分簡潔的方案去有效的解決重復(fù)使用item帶來的問題。

1.認(rèn)識item的重復(fù)使用和viewholder的出現(xiàn)

item的重復(fù)使用目的是為了解決大量的list數(shù)據(jù)消耗大量的視圖空間,而viewholder的出現(xiàn)是系統(tǒng)在解決數(shù)據(jù)顯示的時(shí)候做的一種方案。

而這種方案主要針對的是重復(fù)的item但是數(shù)據(jù)不同。通過tag去綁定在item上然后再取得使用。

保證了每個(gè)已經(jīng)創(chuàng)建的item上一定有個(gè)viewholder,所以每次刷新item的時(shí)候都必須要把數(shù)據(jù)和各種狀態(tài)綁定一遍,否則滑動的時(shí)候就會有重復(fù)顯示的問題。

2.從系統(tǒng)原理上去去重復(fù)

上面我們講了item通過viewholder去解決數(shù)據(jù)重復(fù)的方案,雖然有點(diǎn)繁瑣,但是有效可行。
有人要問:“如果我想改變某個(gè)item的屬性又不想重復(fù)使用導(dǎo)致其他item屬性也改變,什么辦法好用呢?”。
這個(gè)問題最近的項(xiàng)目里我也遇到了。而且是一個(gè)item里面有兩個(gè)子item,這兩個(gè)子item也要一摸一樣,但是不能同時(shí)干擾。
需要做屬性動畫去改變樣式?。。ㄊ遣皇呛艿疤郏慨吘构鞠胍趴?,那我們就按需設(shè)計(jì)唄?。?br/>既然item重復(fù)利用,那么item的子控件都會是同一個(gè)對象。
所以小羽滋生了一種想法,既然控件是一樣的,那么我可以記錄一個(gè)當(dāng)前選中的item或者它的一個(gè)控件,如果是當(dāng)前item并且對應(yīng)的position也是一樣的,那么肯定是當(dāng)前的item可以做改變,當(dāng)滑動到重復(fù)利用的item時(shí),雖然也是當(dāng)前的item但是position卻不一樣,所以這時(shí)候就做默認(rèn)的設(shè)置。
當(dāng)滑回來的時(shí)候滿足前面的條件所以又會繼續(xù)改變。為什么可以這么自信的使用這種方案?原因很簡單。
系統(tǒng)在重復(fù)利用item的時(shí)候是做過處理的,重復(fù)利用的這個(gè)item不可能和上個(gè)item同時(shí)出現(xiàn)在屏幕上。
所以我們不需要像viewholder一樣把每種狀態(tài)都做改變,因?yàn)榧词勾丝痰纳弦粋€(gè)item的屬性會隨著當(dāng)前item屬性改變而改變,放心你是看不見的,所以我們不必?fù)?dān)心這種方案的不可行!

3.源碼分析

//recyclerview的adapter開始BindViewHolder
    @Override
    public void onBindViewHolder(RecViewHolder holder, final int position) {
        if(!Utils.listIsEmpty(mTopPaymentTypes) && mTopPaymentTypes.size() > position){
            PaymentType topPaymentType = mTopPaymentTypes.get(position);
            initPayBtnResource(holder.topPayViewItem, position, topPaymentType);
        }

        if(!Utils.listIsEmpty(mBottomPaymentTypes) && mBottomPaymentTypes.size() > position){
            PaymentType bottomPaymentType = mBottomPaymentTypes.get(position);
            initPayBtnResource(holder.bottomPayViewItem, position,bottomPaymentType);
        }
    }

    //設(shè)置item數(shù)據(jù)
    private void initPayBtnResource(View itemView, int position, PaymentType paymentType) {
        TextView payTypeName = (TextView) itemView.findViewById(R.id.payview_item_name);
        ImageView payTypeImage = (ImageView) itemView.findViewById(R.id.payview_item_image);
        View payTypeLight = itemView.findViewById(R.id.payview_item_light);
        PayTypeSource paySource = mPaySources.get(paymentType);
        if (paySource != null) {
            payTypeName.setText(paySource.getPayTypeName());
            //viewholder綁定item數(shù)據(jù)
            bindItemData(View itemView, int position, PaymentType paymentType);

            //下面這段語句就是解決item重復(fù)使用修改屬性導(dǎo)致其他item出現(xiàn)問題的方案。
            if (mCheckedPayType == paymentType) {
                startLightAnimator();
                mAnimPayLight = payTypeLight;
            } else {
                if (mAnimPayLight == payTypeLight) {
                    endLightAnimator();
                }
            }
        }

        if (isSinglePay) {
            itemView.setOnClickListener(null);
            itemView.setBackgroundResource(R.drawable.pay_item_uncheck);
        } else {
            itemView.setOnClickListener(mClick);
            itemView.setTag(paymentType);
            itemView.setBackgroundResource(R.drawable.pay_item_can_change);
        }
    }

4.總結(jié)該方案!

這個(gè)方案只在單個(gè)item重復(fù)使用的時(shí)候才會被調(diào)用做改變,不需要每個(gè)item都去改變屬性來保持平衡,非常簡單直觀的解決的重復(fù)利用的問題,從代碼的簡潔和系統(tǒng)執(zhí)行的效率上說,都比較優(yōu),缺點(diǎn)就是多占了一個(gè)引用的內(nèi)存,性價(jià)比上來說非常的靠譜。
有人肯定要問后面的endLightAnimator();只結(jié)束了動畫但是屬性還是變了。
這里小羽不得不吐槽一句了:“每個(gè)人的項(xiàng)目需求不一樣,我這里是浮光效果,不選中的時(shí)候我可以直接把浮光隱藏掉就行了,至于這個(gè)屬性在那個(gè)位置都不重要了”。
那么如果是一定要顯示的去改變屬性呢?這個(gè)小羽在3里面就說了,默認(rèn)屬性,就是比如你貼了一個(gè)機(jī)器人,要把他變成瘦機(jī)器人,那么這里end的時(shí)候直接賦值一個(gè)原來的機(jī)器人.方案是對的,問題是解決問題的需求不一樣大家要按照自己的需求去實(shí)現(xiàn)。
原諒小羽不能貼出所有代碼(雖然代碼是自己寫的,但是作為公司商業(yè)化產(chǎn)品,部分保密還是需要的)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI