Fragment的懒加载

前言

本文将介绍实现Fragment的懒加载问题,以下的方式只是我的一种思考。对于这个问题,我认为最好的方式就是有一个BaseFragment,在该Fragment里实现了懒加载的逻辑,当有Fragment需要使用懒加载时,则继承该BaseFragment并实现定义好的方法即可。笔者使用的Fragment来自==import android.support.v4.app.Fragment==包。以下就直接贴代码了吧,在代码里有有比较详细的注释解释。

代码实现

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

public abstract class BaseFragment extends Fragment {

    // 布局成功已经加载的标志位
    private boolean isViewLoaded = false;
    // 数据已经加载的标志位
    private boolean isDataLoaded = false;
    // contentView
    private View contentView;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initConfiguration(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        this.contentView = inflater.inflate(getContentLayout(), container, false);
        this.isViewLoaded = true;
        return contentView;
    }

    @Override
    public void onStart() {
        super.onStart();
        if (getUserVisibleHint() && isViewLoaded){
            if (!isDataLoaded){
                initView(getContentView());
                this.isDataLoaded = loadData();
            }
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getUserVisibleHint() && isViewLoaded ){
            if (!isDataLoaded){
                initView(getContentView());
                this.isDataLoaded = loadData();
            }
        }
    }

    @Override
    public void onDestroyView() {
        // 若View被销毁了,则需要重新创建View,此时应该把标志位复原
        this.isViewLoaded = false;
        isDataLoaded = false;
        super.onDestroyView();
    }

    /**
     * 用于子类得到contentView
     * @return contentView
     */
    public View getContentView(){
        return this.contentView;
    }

    /**
     * 该方法在Fragment的OnCreate方法被执行时调用
     * 主要用于初始化其他模块传递到fragment中的数据
     * 该方法可以选择性地去实现
     * @param bundle 数据包
     */
    protected void initConfiguration(Bundle bundle){}

    /**
     * 在加载布局前调用,用于获取布局文件资源
     * @return 返回一个布局文件的layout资源
     */
    protected abstract int getContentLayout();

    /**
     * 实现View初始化的懒加载
     * 该方法会在OnStart方法执行时调用,或者是在对用户可见时调用,但无论是哪个地方调用,都只会执行一次
     * 在该方法中可以实现findViewById、view的事件初始化等
     * 在OnStart后:若是在OnStart时被调用,则要满足两个条件,1:当前的fragment对用户是可见的;2、布局文件已经
     * 在对用户可见时:若是OnStart是没有调用,而是在对用户可见时被调用,则说明在OnStart方法执行时,当前的fragment对用户不可见
     * @param contentView contentView
     */
    protected void initView(View contentView){}

    /**
     * 实现数据的懒加载
     * 该方法会在OnStart方法执行时调用,或者是在对用户可见时调用,但无论是哪个地方调用,都只会执行一次
     * 在OnStart后:若是在OnStart时被调用,则要满足两个条件,1:当前的fragment对用户是可见的;2、布局文件已经
     * 在对用户可见时:若是OnStart是没有调用,而是在对用户可见时被调用,则说明在OnStart方法执行时,当前的fragment对用户不可见
     * @return 返回Boolean类型的值,若为true:说明已经执行了加载数据的操作;若为false:说明未执行加载数据的操作
     */
    protected abstract boolean loadData();

写在最后

仅供参考,若能帮助到你,那真是太好了。

你可能感兴趣的:(Fragment的懒加载)