當前位置:首頁 » 文件管理 » 不緩存的viewpager

不緩存的viewpager

發布時間: 2022-12-11 09:55:31

㈠ Android-ViewPager源碼解析與性能優化

ViewPager高度設置為wrap_content或者具體的高度值無效,是因為ViewPager的onMeasure方法在度量寬高的時候,在方法體的最開始就直接調用了setMeasuredDimension()方法將自身的寬高度量,但是並沒有在其onMeasure()計算完其具體的子View的寬高之後,重新度量一次自身的寬高

從這里我們可以看到,ViewPager的寬高會受其父容器的寬高的限制,但是並不會因為自身子View的寬高而影響ViewPager的寬高。

看setMeasuredDimension的源碼調用可以看出,當父容器的高度確定時,ViewPager的寬高其實就是父容器的寬高,ViewPager就是在onMeasure方法一進來的時候就直接填充滿整個父容器的剩餘空間。在計算孩子節點之前,就已經計算好了ViewPager的寬高,在計算完孩子節點之後,並不會再去重新計算ViewPager的寬高。

自定義一個ViewPager,根據子View的寬高重新度量ViewPager的寬高。其實做法就是在自定義onMeasure的super.onMeasure(widthMeasureSpec, heightMeasureSpec);之前重新計算heightMeasureSpec,將原本ViewPager接收的父容器的限定的heightMeasureSpec替換成我們自定義的heightMeasureSpec。

但是這樣的做法,會有種問題,即在ViewPager的子View是採用LinearLayout作為根布局的時候,並且給LinearLayout設置了固定的高度值,那麼會出現ViewPager動態高度無效的問題
其實具體的做法,就是仿造measureChild的做法,自定義子View的heightMeasureSpec然後度量整個子View,其實子View的寬度也可以這樣做。

這里其實是源碼層做了限制,在setOffscreenPageLimit中設置了一個默認值,而這個默認值的大小為1

所以從這里可以看出,ViewPager的最小緩存的limit是1,而不能小於1,當小於1的時候就會被強制的設置為1。
而populate()函數就是用來處理ViewPager的緩存的。
populate()的生命周期是與Adapter的生命周期綁定的。
其實在setOffscreenPageLimit()的時候,調用的populate(),而populate()內部調用的

而pupulate(int newCurrentItem)方法在另一處調用的地方就是在setCurrentItem。
其實ViewPager緩存都是基於ItemInfo這個類來進行的,

看下ViewPager.addNewItem的源碼
其實ViewPager.addNewItem就是通過調用Adapter.instantiateItem來創建對應的View,並且將View保存到ItemInfo中的object屬性,並且判斷ViewPager緩存中是否已經有ItemInfo,如果沒有,則添加,如果有則做修改替換

從分析FragmentStatePagerAdapter來看,setUserVisibleHint方法會優先於Fragment的生命周期函數 執行。因為在FragmentStatePagerAdapter中提交事務,是在調用finishUpdate方法中進行的,只有提交事務的時候,才會去執行Fragment的生命周期。
FragmentStatePagerAdapter中的instantiateItem和destroyItem都實現了對fragment的事務的添加和刪除,而finishUpdate實現了事務的提交,所以在實現FragmentStatePagerAdapter的時候,並不需要重寫instantiateItem和destroyItem

㈡ ViewPager詳解

如果你不使用setoffscreenpagelimit(int limit)這個方法去設置默認載入數的話是會默認載入頁面的左右兩頁的,也就是說當你進入viewpager第一頁的時候第二頁和第一頁是會被一起載入的,這樣同時載入就會造成一些問題,試想我們如果設置了setoffscreenpagelimit為3的話,那麼進入viewpager以後就會同時載入4個fragment,像我們平時的項目中在這些fragment中一般都是會發送網路請求的,也就是說我們有4個fragment同時發送網路請求去獲取數據,這樣的結果顯而易見給用戶的體驗是不好的(如:浪費用戶流量,造成卡頓等等)。

ViewPager的預載入機制。默認緩存當前頁面的前後各一個。

參考: ViewPager懶載入

PagerAdapter有兩個子類:
FragmentPagerAdapter和FragmentPagerStateAdapter

參考: PagerAdapter深度解析和實踐優化

ViewPager2實現是RecyclerView
ViewPager2的Adapter是FragmentStateAdapter

㈢ android studio viewpager怎麼讓其不緩存

設置單實例。
假如你一個Fragment名字是TestFragment,你可以這樣
TestFragment mTestFragment;
public TestFragment getInstance(){
if( TestFragment == null)
mTestFragment = new TestFragment();

return mTestFragment;
}

㈣ ViewPage在運行的時候,各個fragment的執行過程是什麼樣的

setUserVisibleHint就是告訴系統,fragment可見的時候才載入數據
如果fragment不多的話, 可以在activty裡面直接初始化默認內容,等到翻個某個fragment的時候再載入網路或者本地內容。
ViewPager默認會緩存三頁,即當前頁和左右兩頁。
滑動到第三頁時,第一頁已經不緩存了,就調用PagerAdapter里的destroyItem方法銷毀了,再回來時調用了PagerAdapter的instantiateItem重新創建了一個。FragmentPagerAdapter的緩存策略更復雜一些,參見[FragmentPagerAdapter與FragmentStatePagerAdapter區別]

㈤ 求大神解決!!android viewpager緩存,fragment動畫

取消viewpager預載入,重寫一個基類fragment,判斷該fragment是否顯示,沒顯示就不載入界面。你網路,我手機端寫代碼費時,網路viewpager取消預載入,一大堆,都挺好懂得沒有多少代碼。

㈥ 談談RecyclerView中的緩存

Android深入理解RecyclerView的緩存機制

RecyclerView在項目中的使用已經很普遍了,可以說是項目中最高頻使用的一個控制項了。除了布局靈活性、豐富的動畫,RecyclerView還有優秀的緩存機制,本文嘗試通過源碼深入了解一下RecyclerView中的緩存機制。

RecyclerView做性能優化要說復雜也復雜,比如說布局優化,緩存,預載入等等。其優化的點很多,在這些看似獨立的點之間,其實存在一個樞紐:Adapter。因為所有的ViewHolder的創建和內容的綁定都需要經過Adaper的兩個函數onCreateViewHolder和onBindViewHolder。

因此我們性能優化的本質就是要減少這兩個函數的調用時間和調用的次數。如果我們想對RecyclerView做性能優化,必須清楚的了解到我們的每一步操作背後,onCreateViewHolder和onBindViewHolder調用了多少次。因此,了解RecyclerView的緩存機制是RecyclerView性能優化的基礎。

為了理解緩存的應用場景,本文首先會簡單介紹一下RecyclerView的繪制原理,然後再分析其緩存實現原理。

RecyclerView滑動時會觸發onTouchEvent#onMove,回收及復用ViewHolder在這里就會開始。我們知道設置RecyclerView時需要設置LayoutManager,LayoutManager負責RecyclerView的布局,包含對ItemView的獲取與復用。以LinearLayoutManager為例,當RecyclerView重新布局時會依次執行下面幾個方法:

上述的整個調用鏈:onLayoutChildren()->fill()->layoutChunk()->next()->getViewForPosition(),getViewForPosition()即是是從RecyclerView的回收機制實現類Recycler中獲取合適的View,下面主要就來從看這個Recycler#getViewForPosition()的實現。

上述邏輯用流程圖表示:

RecyclerView在Recyler裡面實現ViewHolder的緩存,Recycler裡面的實現緩存的主要包含以下5個對象:

public final class Recycler {

final ArrayList mAttachedScrap = new ArrayList<>();

ArrayList mChangedScrap = null;

RecyclerView在設計的時候講上述5個緩存對象分為了3級。每次創建ViewHolder的時候,會按照優先順序依次查詢緩存創建ViewHolder。每次講ViewHolder緩存到Recycler緩存的時候,也會按照優先順序依次緩存進去。三級緩存分別是:

使用自定義ViewCacheExtension後,view離屏後再回來不會走onBindViewHolder()方法。

holder.setIsRecyclable(false),這樣的話每次都會走onCreateViewHolder()和onBindViewHolder()方法

1.提前初始化viewHolder,放到緩存池中

viewPool.putRecycledView(adapter.onCreateViewHolder(recyclerView, 1))

2.提前初始化view,在onCreateViewHolder的時候去取view

3.自定義ViewCacheExtension

4.適當的增加cacheSize

4.公用緩存池,比如多個viewPager+fragment場景使用,或者全局單利緩存池,感覺用戶不大。

有2中做法有值

第一種

第二種

不會,因為prefetch(GapWorker中的一個方法)之後mViewCacheMax會變成mRequestedCacheMax + extraCache

有2種方式可以讓緩存失效

第一種

recyclerView.setItemViewCacheSize(-1)

第二種

recyclerView.setItemViewCacheSize(0)

layoutManager.isItemPrefetchEnabled = false

設置不緩存後,來回滑動讓view進入屏幕離開屏幕,viewHolder的item時會多次走onBindViewHolder()方法。

㈦ viewpager的緩存載入機制

viewpager有緩存預載入機制,主要使用setOffscreenPageLimit(int limit) 

1.setOffscreenPageLimit(int limit) 解釋 

   緩存:左右都會緩存limit個頁面,比如limit緩存數量是2,在tab3,那會緩存tab1、tab2、tab4、tab5,如果其他界面已經緩存過的話會調用onDestroyView銷毀

   預載入:limit緩存數量是2,如果在tab1會預載入tab2、tab3,切換到tab2的話會預載入tab4,

2.viewpager源碼分析

viewpager繼承viewgroup當然也要走onmeasure,ondraw,onlayout方法,主要看onmeasure裡面的populate()方法

這里的mAdapter是PagerAdapter

fragmentpageradapter就是你寫的適配器,接下來看具體實現

所以我們可以用uservisiblehint來懶載入,需要注意的是uservisiblehint不是生命周期函數,初始化的時候他的執行在fragment的onattch之前

Fragment 生命周期按先後順序:onAttach -> onCreate -> onCreatedView -> onActivityCreated -> onStart -> onResume ->onPause -> onStop -> onDestroyView -> onDestroy -> onDetach

㈧ 深入解析ViewPager懶載入

ViewPager默認情況的載入,會默認預載入一個的布局到ViewPager中,這就時ViewPager的預載入。setOffscreenPageLimit可以通過這個方法去設置預載入布局的個數。

從上面可以看出,預載入的頁面個數大於等於1。

在緩存數量更新的時候,要執行緩存方法polulate()。去看看裡面做了啥事

前面提到了創建ViewPager.ItemInfo,這個是什麼

注釋①:調用instantiateItem來創建object,在FragmentPagerAdapter的instantiateItem這個方法中,創建的就是fragment。所以緩存的就是fragment,fragment在創建時,會有ui操作,網路操作,在還未可見的時候,就去初始化fragment非常消耗性能,所以懶載入的方式來載入,不去緩存fragment。

㈨ ViewPager的緩存頁面 與 預載入

1、在setUserVisibleHint(boolean isVisibleToUser),判斷參數isVisibleToUser為true時才去載入數據,false則停止載入

2、解決崩潰:由於setUserVisibleHint(boolean isVisibleToUser)在onCreateView()之前執行,有可能view還未被創建。所以需要設置一個tag,在onCreateView()中置為true。
然後在tag為true時才去載入/停止載入數據

3、解決第一次進入不載入:第一次進入,setUserVisibleHint(boolean isVisibleToUser)在onCreateView()之前執行,載入數據的邏輯並未執行,
所以需要我們在onCreateView()中手動執行載入邏輯,在getUserVisibleHint()為true的時候執行。

Fragment 生命周期按先後順序:
onAttach -> onCreate -> onCreatedView -> onActivityCreated -> onStart -> onResume ->
onPause -> onStop -> onDestroyView -> onDestroy -> onDetach

ViewPager + Fragment 的實現我們需要關注的幾個生命周期有: onCreatedView + onResume + onPause + onDestroyView非生命周期函數:setUserVisibleHint + onHiddenChanged

㈩ ViewPager系列文章(一)- ViewPager源碼分析及載入頁面原理圖

1>:點擊 viewPager.setAdapter進入下邊源碼,會調用 populate() 方法,這個方法作用是創建和銷毀子條目(子item):

在populate()方法中:
創建ItemView:mAdapter.instantiateItem(this, position);
銷毀ItemView:mAdapter.destroyItem(this, pos, ii.object);
所以由ViewPager的源碼可以看出,ViewPager里邊無論放多少個頁面都不會內存溢出,它會不斷的去創建和銷毀view;

和 ListView、RecyclerView不一樣,ListView、RecyclerView是會不斷的復用view,而viewpager是不斷的創建和銷毀view

輪播圖剛打開默認顯示當前頁,是第一頁,默認會緩存左右兩個頁面,如果左邊沒有,只有右邊有,那麼右邊是第0頁,當前頁是第一頁;
如果你滑動到第1頁,ViewPager會默認把 左邊第0頁 和 右邊第2頁 創建出來;
如果你滑動到第2頁,ViewPager會默認把第1頁和第3頁創建出來,而原來的第0頁就會變成需要銷毀的頁面;

如果想要緩存多頁,可以調用setOffscreenPageLimit()方法:
setOffscreenPageLimit(1):ViewPager機制默認就是緩存1,表示左邊、右邊各緩存1頁,加上自己,總共是3頁,其餘頁面全部銷毀;
setOffscreenPageLimit(2):表示默認給左右各緩存2頁,共4頁,加上自己,總共緩存5頁,其餘頁面全部銷毀;
setOffscreenPageLimit(3):表示默認給左右各緩存3頁,共6頁,加上自己,總共緩存7頁,其餘頁面全部銷毀;

因為 smoothScrollTo()滑動方法也調用populate(),而populate()方法維護了當前顯示頁面和 左右緩存的頁面,就能做到無限滑動而不出問題;

A:從populate()源碼中可知:先判斷頁面是否在緩存范圍內:如果在,則addNewItem添加進來,否則在destroyItem掉;
B:ViewPager會緩存左右兩邊頁面+1(當前顯示頁面),默認認為當前頁面的 左右兩邊各有1個,用戶可以手動調用setOffscreenPageLimit()方法設置數量,如果傳的值小於1,就默認設置為1;
ViewPager實際示意圖如下:

熱點內容
數獨基本演算法 發布:2025-09-19 13:14:29 瀏覽:528
python獲取ip代理伺服器 發布:2025-09-19 12:55:35 瀏覽:230
h5加密 發布:2025-09-19 12:13:11 瀏覽:782
網貸系統源碼下載 發布:2025-09-19 10:56:45 瀏覽:114
腳本被黑 發布:2025-09-19 10:51:27 瀏覽:507
android自定義命名空間 發布:2025-09-19 10:31:34 瀏覽:461
凱立德導航文件夾名稱 發布:2025-09-19 10:31:27 瀏覽:34
獅山編程 發布:2025-09-19 10:14:45 瀏覽:786
androidshape畫圓 發布:2025-09-19 10:13:21 瀏覽:837
c語言if復合語句 發布:2025-09-19 10:12:30 瀏覽:718