Fragment禁止預加載


項目中經常會用到ViewPager+Fragment組合,然而,有一個很讓人頭疼的問題就是,去加載數據的時候由於ViewPager的內部機制所限制,所以它會默認至少預加載一個。

1、既然說是ViewPager的內部機制,那么我們可不可以設置ViewPager的預加載為0?如下:

vp.setOffscreenPageLimit(0);

No,結果發現根本行不通。。。查看源碼:

   private static final int DEFAULT_OFFSCREEN_PAGES = 1;
    /**
     * Set the number of pages that should be retained to either side of the
     * current page in the view hierarchy in an idle state. Pages beyond this
     * limit will be recreated from the adapter when needed.
     *
     * <p>This is offered as an optimization. If you know in advance the number
     * of pages you will need to support or have lazy-loading mechanisms in place
     * on your pages, tweaking this setting can have benefits in perceived smoothness
     * of paging animations and interaction. If you have a small number of pages (3-4)
     * that you can keep active all at once, less time will be spent in layout for
     * newly created view subtrees as the user pages back and forth.</p>
     *
     * <p>You should keep this limit low, especially if your pages have complex layouts.
     * This setting defaults to 1.</p>
     *
     * @param limit How many pages will be kept offscreen in an idle state.
     */
    public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " + DEFAULT_OFFSCREEN_PAGES);
            limit = DEFAULT_OFFSCREEN_PAGES;
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }

所以即使你設置為0,還是會設置默認值1,所以這個方法是行不通的。

2、Fragment里面有個setUserVisibleHint(boolean isVisibleToUser)方法,所以考慮在此去處理數據。

 

public class LazyFragment extends Fragment {
    protected PullToRefreshListView mPullToRefreshListView;
    protected EmptyLayout mEmptyLayout;
    protected ListView mListView;
    protected int maxId = 0;
    //標志位,標志已經初始化完成
    protected boolean isInit = false;
    //是否已被加載過一次,第二次不再去請求數據
    protected boolean mHasLoadedOnce;
    private View view;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.activity_common_list, null);
        initView(view);
        return view;
    }


    public void initView(View view) {
        mPullToRefreshListView = (PullToRefreshListView) view.findViewById(R.id.pull_refresh_list);
        mEmptyLayout = (EmptyLayout) view.findViewById(R.id.error_layout);
        isInit = true;
        isCanLoadData();
    }

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

    /**
     * 禁止預加載
     */
    private void isCanLoadData() {
        if (!isInit) {
            return;
        }
        if (getUserVisibleHint() && !mHasLoadedOnce) {
            loadData();
        }
    }

    protected void loadData() {
    //數據加載成功后
    mHasLoadedOnce = true;
  }
}

 在loadData()中加載數據,在數據加載成功之后將mHasLoadedOnce置為true即可。以上完美解決因為Fragment的懶加載導致的,比如:預先請求服務器接口,造成服務器額外壓力等問題~

   By LiYing


免責聲明!

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



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