RecycleView緩存

RecyclerView根據(jù)不同的狀態(tài)可以分為:屏幕內(nèi)緩存杨拐、屏幕外緩存、自定義緩存褥符、緩存池鹃操。RecyclerView是通過內(nèi)部類Recycler來管理緩存况既。
一級(jí)緩存:屏幕內(nèi)緩存(mAttachedScrap)
屏幕內(nèi)緩存指在屏幕中顯示的ViewHolder,這些ViewHolder會(huì)緩存在mAttachedScrap组民、mChangedScrap中 :

mChangedScrap 表示數(shù)據(jù)已經(jīng)改變的ViewHolder列表棒仍,需要重新綁定數(shù)據(jù)(調(diào)用onBindViewHolder)
mAttachedScrap 未與RecyclerView分離的ViewHolder列表
二級(jí)緩存:屏幕外緩存(mCachedViews)
用來緩存移除屏幕之外的 ViewHolder,默認(rèn)情況下緩存容量是 2臭胜,可以通過 setViewCacheSize 方法來改變緩存的容量大小莫其。如果 mCachedViews 的容量已滿癞尚,則會(huì)優(yōu)先移除舊 ViewHolder,把舊ViewHolder移入到緩存池RecycledViewPool 中乱陡。

三級(jí)緩存:自定義緩存(ViewCacheExtension)
給用戶的自定義擴(kuò)展緩存浇揩,需要用戶自己管理 View 的創(chuàng)建和緩存,可通過Recyclerview.setViewCacheExtension()設(shè)置憨颠。

四級(jí)緩存:緩存池(RecycledViewPool )
ViewHolder 緩存池胳徽,在mCachedViews中如果緩存已滿的時(shí)候(默認(rèn)最大值為2個(gè)),先把mCachedViews中舊的ViewHolder 存入到RecyclerViewPool爽彤。如果RecyclerViewPool緩存池已滿养盗,就不會(huì)再緩存。從緩存池中取出的ViewHolder 适篙,需要重新調(diào)用bindViewHolder綁定數(shù)據(jù)往核。

按照 ViewType 來查找 ViewHolder
每個(gè) ViewType 默認(rèn)最多緩存 5 個(gè)
可以多個(gè) RecyclerView 共享 RecycledViewPool
RecyclerViewPool底層是使用了SparseArray來分開存儲(chǔ)不同ViewType的ViewHolder集

列表刷新優(yōu)化:
對(duì)于類似于從列表進(jìn)詳情關(guān)注某個(gè)用戶后,回到列表客戶端刷新列表關(guān)注狀態(tài)數(shù)據(jù)(可能不止當(dāng)前item需要改變關(guān)注狀態(tài))
本地刷新嚷节,可以通過反射修改緩存數(shù)據(jù)聂儒。
1、直接修改Adapter對(duì)應(yīng)的List數(shù)據(jù)硫痰,但不執(zhí)行notifyDataSetChanged()方法
2衩婚、屏內(nèi)緩存找到對(duì)于ViewHolder直接更新UI
3、瓶外緩存可以通過反射找到對(duì)于ViewHolder再更改UI(關(guān)鍵點(diǎn))
屏外緩存不會(huì)觸發(fā)onBindViewHolder()方法需要手動(dòng)反射修改UI

4效斑、緩存池不需做任何操作非春,當(dāng)滑動(dòng)到對(duì)應(yīng)item會(huì)回調(diào)onBindViewHolder方法,然后更改UI

列表頁收到廣播后直接修改數(shù)據(jù)和更新UI

屏內(nèi)緩存可以直接修改

         // 關(guān)注狀態(tài)變化廣播
          @Override
           public void onFollowChange(String follow_user_id, int follow_status) {
               if (!hasInit)
                   return;

               if (videoList != null && videoList.size() > 0) {
                   for (int i = 0; i < videoList.size(); i++) {
                       if (follow_user_id.equals(videoList.get(i).getUser_id())) {
                           videoList.get(i).setFollow_status(follow_status);
                           RecyclerView.ViewHolder viewHolder = rc_video_list.findViewHolderForAdapterPosition(i);
                           if (viewHolder != null && viewHolder instanceof VideoAdapter.VideoViewHolder) {
                               VideoAdapter.VideoViewHolder itemHolder = (VideoAdapter.VideoViewHolder) viewHolder;
                               itemHolder.bindDataFollow(type, videoList.get(i));//更新UI
                           }
                       }
                   }
                   RecycleViewCachedViewBindViewUtils.bindView(rc_video_list, new RecycleViewCachedViewBindViewUtils.BindView() {
                       @Override
                       public void bindView(RecyclerView.ViewHolder viewHolder,int positon) {
                           if (viewHolder != null && viewHolder instanceof VideoAdapter.VideoViewHolder) {
                               VideoAdapter.VideoViewHolder itemHolder = (VideoAdapter.VideoViewHolder) viewHolder;
                               itemHolder.bindDataFollow(type,videoList.get(positon));//更新UI
                           }
                       }
                   });
               } else {
                   if (type == Constants.FOLLOW_MV) {
                       initData();
                       return;
                   }
               }
           }

更新屏外緩存UI

package com.aimei.meiktv.util;

import android.support.v7.widget.RecyclerView;
import java.lang.reflect.Field;
import java.util.ArrayList;

/**
 * 更新CachedView里的ViewHoler
 * by  xingchun  2020-12-18
 */
public class RecycleViewCachedViewBindViewUtils {
    public static void bindView(RecyclerView rc_video_list, BindView bindView) {
        try {
            Field field_mRecycler = RecyclerView.class.getDeclaredField("mRecycler");
            field_mRecycler.setAccessible(true);
            RecyclerView.Recycler recycler = (RecyclerView.Recycler) field_mRecycler.get(rc_video_list);
            Field field_mCachedViews = RecyclerView.Recycler.class.getDeclaredField("mCachedViews");//找到屏外緩存
            field_mCachedViews.setAccessible(true);
            ArrayList<RecyclerView.ViewHolder> mCachedViews = (ArrayList<RecyclerView.ViewHolder>) field_mCachedViews.get(recycler);
            if (mCachedViews != null && mCachedViews.size() > 0) {
                for (int i = 0; i < mCachedViews.size(); i++) {
                    RecyclerView.ViewHolder viewHolder = mCachedViews.get(i);
                    bindView.bindView(viewHolder, viewHolder.getAdapterPosition());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public interface BindView {
        void bindView(RecyclerView.ViewHolder viewHolder, int positon);
    }
}

更新UI

  public void bindDataFollow(int type, NewVideoV3 video) {
            if (video==null){
                fv_follow_view.setVisibility(View.GONE);
                return;
            }
            fv_follow_view.bindData(video);
            if ( video.getFollow_status() == 1
                    || video.getFollow_status() == 2
                    || (!TextUtils.isEmpty(AppUtil.getUserId()) && AppUtil.getUserId().equals(video.getUser_id()))) {//關(guān)注  (自己或別人的)作品不顯示關(guān)注
                fv_follow_view.setVisibility(View.GONE);
            } else {//未關(guān)注
                fv_follow_view.setVisibility(View.VISIBLE);
            }
        }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鳍悠,一起剝皮案震驚了整個(gè)濱河市税娜,隨后出現(xiàn)的幾起案子坐搔,更是在濱河造成了極大的恐慌藏研,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件概行,死亡現(xiàn)場(chǎng)離奇詭異蠢挡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凳忙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門业踏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涧卵,你說我怎么就攤上這事勤家。” “怎么了柳恐?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵伐脖,是天一觀的道長(zhǎng)热幔。 經(jīng)常有香客問我,道長(zhǎng)讼庇,這世上最難降的妖魔是什么绎巨? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮蠕啄,結(jié)果婚禮上场勤,老公的妹妹穿的比我還像新娘。我一直安慰自己歼跟,他們只是感情好和媳,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嘹承,像睡著了一般窗价。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叹卷,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天撼港,我揣著相機(jī)與錄音,去河邊找鬼骤竹。 笑死帝牡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蒙揣。 我是一名探鬼主播靶溜,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼懒震!你這毒婦竟也來了罩息?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤个扰,失蹤者是張志新(化名)和其女友劉穎瓷炮,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體递宅,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娘香,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了办龄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烘绽。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖俐填,靈堂內(nèi)的尸體忽然破棺而出安接,到底是詐尸還是另有隱情,我是刑警寧澤英融,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布盏檐,位于F島的核電站呀打,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏糯笙。R本人自食惡果不足惜贬丛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望给涕。 院中可真熱鬧豺憔,春花似錦、人聲如沸够庙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耘眨。三九已至昼榛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剔难,已是汗流浹背胆屿。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留偶宫,地道東北人非迹。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像纯趋,于是被迫代替她去往敵國(guó)和親憎兽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 分析RV的緩存機(jī)制吵冒,先思考一下什么時(shí)候用到緩存機(jī)制纯命,從源碼的哪個(gè)角度去看,緩存肯定是在滑動(dòng)的時(shí)候去做的痹栖,所以我們從...
    leap_閱讀 517評(píng)論 0 2
  • 首先看一下為何說RecycleView(主要有適配器模式亿汞,觀察者模式adapter通知更新UI)中的adapter...
    唯愛_0834閱讀 713評(píng)論 0 7
  • 前沿 Android新增的Recyclerview主要用于代替ListView。Recyclerview可擴(kuò)展性強(qiáng)...
    凱玲之戀閱讀 8,237評(píng)論 7 11
  • 計(jì)算機(jī)領(lǐng)域常用的提高效率辦法是使用緩存结耀,一級(jí)不夠就上多級(jí)緩存留夜,RecyclerView也采用了緩存策略匙铡。緩存的單位...
    賴益文閱讀 745評(píng)論 0 0
  • RecyclerView為什么強(qiáng)制我們實(shí)現(xiàn)ViewHolder模式图甜? 關(guān)于這個(gè)問題,我們首先看一下ListView...
    Johnson_Coding閱讀 534評(píng)論 0 0