ViewPager -- Fragment 切換卡頓 性能優化


當ViewPager切換到當前的Fragment時,Fragment會加載布局並顯示內容,如果用戶這時快速切換ViewPager,即Fragment需要加載UI內容,而又頻繁地切換Fragment,就容易產生卡頓現象(類似在ListView快速滑動的同時加載圖片容易卡頓)。

  

===========================、處理方案 ===============================

1.Fragment輕量化

 

如果ViewPager加載的Fragment都比較輕量,適當精簡Fragment的布局,可提高Fragment加載的速度,從而減緩卡頓現象。

 

2.防止Fragment被銷毀

 

ViewPager在切換的時候,如果頻繁銷毀和加載Fragment,就容易產生卡頓現象,阻止Fragment的銷毀可有效減緩卡頓現象。

 

(1)    在PagerAdapter里覆蓋destroyItem方法可阻止銷毀Fragment

 @Override       
public void destroyItem(ViewGroup container, int position, Object object) {
    //super.destroyItem(container, position, object);
}

 

(2)    通過PagerAdapter的setOffscreenPageLimit()方法可以設置保留幾個Fragment,適當增大參數可防止Fragment頻繁地被銷毀和創建。

風險:在Fragment比較多的情況下,部分低端機型容易產生OOM問題。


3.Fragment內容延遲加載

(1) 描述

 

在切換到當前Fragment的時候,並不立刻去加載Fragment的內容,而是先加載一個簡單的空布局,然后啟動一個延時任務,延時時長為T,當用戶在該Fragment停留時間超過T時,繼續執行加載任務;而當用戶切換到其他Fragment,停留時間低於T,則取消該延時任務。

 

(2) 具體操作

首先,設置延遲任務

 

 private Runnable LOAD_DATA = new Runnable() {        
@Override
public void run() {
//在這里數據內容加載到Fragment上
}
};

啟動任務

 

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    //初始化視圖,這里最好先設置一個進度對話框,提示用戶正在加載數據
    initView();
    //啟動任務,這里設置500毫秒后開始加載數據    handler.postDelayed(LOAD_DATA,500)
    return view;
}

若用戶切換到其他Fragment則取消任務

 

//判斷Fragment是否可視的重載方法
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
  super.setUserVisibleHint(isVisibleToUser);
    if(!isVisibleToUser)
     mHandler.removeCallbacks(LOAD_DATA);
}

(3) 注意

 

使用setUserVisibleHint判斷用戶是否切換到其他Fragment,這樣的做法有個缺陷,因為會在ViewPager開始滑動的時候取消延時任務,而在滑動偏移量不足的情況下,ViewPager會繼續回滾到當前Fragment,導致當前Fragment的加載任務被取消而又不會重新啟動加載任務。

  這里我使用的做法是,給ViewPager增加一個OnPageChangeListener,,該監聽器的onPageSelected(position)能監聽ViewPager當前切換到哪個Fragment,在這里將其他Fragment的延遲加載任務取消掉。

 

================項目中用到的代碼片段==========================================================

Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        getActivity().runOnUiThread(new Runnable() {
                            
                            @Override
                            public void run() {
                                // TODO Auto-generated method stub
                                
                                geticard();
                            }
                        });
                    }
                }, 500);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM