天天看点

Fragment懒加载优雅实现

应用场景

  • 我们知道,在viewpage中加载多个fragment默认会预加载1项数据。而当左右滑动切换时,如果加载的fragment过多,前面已经加载的fragment界面是会被回收的。这就造成返回的时候我们又重新创建了一个fragment对象。在用户体验上,效果并不那么好。

我们要实现的效果

Fragment懒加载优雅实现

可以看到多个fragment之间做到了无缝切换。

直接上代码

本项目基于mvvm+dataBinding模式。

新建BaseLazyFragment
public abstract class BaseLazyFragment<T extends ViewDataBinding> extends Fragment {
    /**
     * @param isVisibleToUser
     */
    public boolean inInit = false;
    public boolean isLoad = false;
    private LayoutInflater mInflater;
    private ViewGroup mContainer;
    private T t;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        mInflater = inflater;
        mContainer = container;
        if (t != null && t.getRoot() != null) {
            return t.getRoot();
        } else {
            initFragment();
            return t.getRoot();
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        inInit = true;
        initData();
        isCanLoadData();
    }
    public T setBinding(T k) {
        k = DataBindingUtil.inflate(mInflater, setContentView(), mContainer, false);
        t = k;
        return k;
    }

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

    public abstract void initFragment();
    public abstract void initData();

    private void isCanLoadData() {
        if (!inInit) {
            return;
        }
        if (getUserVisibleHint()) {
            lazyLoad();
            isLoad = true;
        } else {
            if (isLoad) {
                stopLoad();
            }
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        inInit = false;
        isLoad = false;
    }

    public abstract int setContentView();

    public abstract void lazyLoad();

    public void stopLoad() {

    }
}


           

两个标记:inInit用来标记 试图是否加载完毕,isLoad用来标记是否已经加载过数据。

setUserVisibleHint方法表示试图是否已经可见。通过getUserVisibleHint()获取值如果为true则加载数据。

使用

新建fragment继承该基类即可。

值得注意的是onCreateView方法中通过判断view是否存在避免重新创建view以达到完美滑动过度。

if (t != null && t.getRoot() != null) {
            return t.getRoot();
        } else {
            initFragment();
            return t.getRoot();
        }
           

附上完整项目地址:https://github.com/dingshuangdian/hodgepodge

欢迎留言交流

继续阅读