Fragment(androidx.fragment)懒加载

1.原因

在开发过程中我们会遇到Viewpager嵌套Fragment的情况,这时如果每个Fragment中都含有耗时操作(如网络请求等),由于Viewpager有预加载功能,此时无论Fragment是否可见,都已被创建。这样会造成用户的流量消耗、耗时等。

2.setUserVisibleHint()方法被移除

一般的做法是结合Fragment 有一个非生命周期的

setUserVisibleHint(boolean isVisibleToUser)

回调方法来完成懒加载功能,但是在

androidx.fragment.app.FragmentPagerAdapter

中此方法被移除了。下面是开发者文档中提到的


image

3.生命周期

  • 1)创建Fragment
onAttach() —> onCreate() —> onCreateView() —> onActivityCreated() —> onStart() —> onResume()
  • 2)从桌面回到Fragment / 解锁
onStart() —> onResume()
  • 3)切换回本身的Fragment
onCreateView() —> onActivityCreated() —> onStart() —> onResume()

所以我们可以在OnResume中来判断此Fragment是否对用户可见来完成懒加载

public abstract class BaseFragment<V extends ViewDataBinding> extends Fragment{
    protected V binding;
    private View mView;
    private boolean isViewCreated; // 界面是否已创建完成
    private boolean isVisibleToUser; // 是否对用户可见
    private boolean isDataLoaded; // 数据是否已请求, isNeedReload()返回false的时起作用

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

        //避免重复创建View
        if (mView == null){
            binding = DataBindingUtil.inflate(inflater, initContentView(inflater, container, savedInstanceState), container, false);
            mView = binding.getRoot();
            isViewCreated = true;
            tryLoadData();
        }else {
            ViewGroup parent = (ViewGroup) mView.getParent();
            if (parent != null){
                parent.removeView(mView);
            }
        }

        return mView;
    }

    public abstract void initData();

    public abstract int initContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);

    /**
     * fragment再次可见时,是否重新请求数据,默认为flase则只请求一次数据
     *
     * @return
     */
    protected boolean isNeedReload() {
        return false;
    }

    @Override
    public void onResume() {
        super.onResume();
        isVisibleToUser = true;
        tryLoadData();
    }

    private void tryLoadData() {
        if (isViewCreated && isVisibleToUser && !isDataLoaded) {
            initData();
            isDataLoaded = true;
        }
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容