ViewPager + Fragment中對Fragment數據懶加載的實現

背景

  • 項目中不可避免會用到,這裏記錄一下,方便自己和同學們,好記性不如爛筆頭。

  • 理解後就不用專門記了,因爲也確實沒有太多複雜的東西。

  • 因爲 viewPager 的預加載機制,所以我們爲了讓 fragment 使用起來更加流暢,提升性能,所以需要對 fragment 做一個懶加載的操作,當 fragment 對用戶不可見時不加載數據。


分析實現

  • 最開始的 fragment 代碼如下:
package com.example.myapplication.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.myapplication.R;

/**
 * 懶加載寫法
 */
public class MyFragment extends Fragment {


    public MyFragment() {
        // Required empty public constructor
    }

    private View view;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        if (view == null && savedInstanceState == null){
            view = inflater.inflate(R.layout.fragment_my, container, false);
        }

        return view;
    }
}

這個沒有疑問。


  • 只有當 fragment 對用戶可見fragment 的視圖已經加載完成以後,我們纔可以做對應的數據加載操作,所以這裏引入兩個布爾變量分別標識,如下圖示:
    在這裏插入圖片描述

初始化均賦值爲 false。


  • 因爲是跟 viewPager 相結合,所以在 fragment 中判斷對用戶是否可見我們重寫setUserVisibleHint生命週期方法進行判斷,如下圖示:
    在這裏插入圖片描述

  • 在 onCreateView 方法中對view已經加載完成標識置爲 true,如下圖示:
    在這裏插入圖片描述

  • 所以此時當對用戶可見且 view 已經加載完成後,我們在 onResume 方法中做懶加載操作,如下圖示:
    在這裏插入圖片描述

  • 此時做完懶加載操作後,記得恢復先前的標識,防止數據重複加載。如下圖示:
    在這裏插入圖片描述

  • 因爲預加載機制,有的 fragment 已經初始化完成了,也執行到了 onResume 生命週期方法,但是這時候對用戶不可見,所以在 onResume 方法裏的 lazyLoad 方法並不會執行,那麼這種情況下也就不會執行懶加載操作。

  • 不過這個時候,當滑動fragment 對用戶可見時,會回調 setUserVisibleHint 生命週期方法,所以我們可以在這裏面進行懶加載操作,也就解決了上面說的情況。如下圖示:
    在這裏插入圖片描述


  • 最後,可能有的同學會說,你第一次創建fragment的時候,在 setUserVisibleHint 中調用了 lazyLoad 方法,也在 onResume 中調用了 LazyLoad 方法,你這不是就重複加載數據了嗎?

  • 說明如下:因爲 setUserVisibleHint 方法會優先於 onCreateView 方法執行(如下圖示),所以此時 view 還未加載完,那麼上面所說的 isViewCreated 標識值爲 false ,所以此時 lazyLoad 方法其實並不會執行。因爲只有同時滿足對用戶可見且 view 已經加載完成纔去加載數據。
    在這裏插入圖片描述
    所以問題得以解決。


完整代碼

package com.example.myapplication.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.myapplication.R;

/**
 * 懶加載寫法
 */
public class MyFragment extends Fragment {

    private boolean isVisible = false;// 對用戶是否可見標識
    private boolean isViewCreated = false;// view是否已經加載完成標識

    public MyFragment() {
        // Required empty public constructor
    }

    private View view;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        if (view == null && savedInstanceState == null){
            view = inflater.inflate(R.layout.fragment_my, container, false);
        }

        isViewCreated = true;// view 已經加載
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        lazyLoad();
    }

    /**
     * 延遲加載 - 對用戶可見且view已經加載完成
     */
    private void lazyLoad() {
        if(isVisible && isViewCreated){
            loadData();
            reset();// 恢復標識,防止重複加載
        }
    }

    /**
     * 恢復標記 防止重複加載
     */
    private void reset(){
        isViewCreated = false;
        isVisible = false;
    }

    /**
     * 加載數據操作
     */
    private void loadData() {

    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser){

            isVisible = true;// 對用戶可見
            lazyLoad();

        }else {
            isVisible = false;// 對用戶不可見
        }
    }
}

上面就是完整的一個懶加載實現的代碼,希望對同學們加深理解有幫助。


技術永不眠,我們下期見!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章