fragment 懒加载

fragment 的懒加载

  • 懒加载

什么是懒加载:
只有在 fragment 显示在界面的时候,才进行数据的加载

懒加载类别:
不同 fragment 的添加方式,需要采用不同的懒加载处理方法

fragment 添加方式:

  1. replace()
  2. add()/hide()/show()
  3. viewpager + fragment

replace()

/**
 * 以replace()的方式添加fragment到指定布局R.id.layout_fragment
 */
private void showFragment(Fragment fragment) {
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.replace(R.id.layout_fragment, fragment);
    transaction.commit();
}

每次均是添加新的 fragment 实例,数据需要重新加载
选择合适的生命周期即可

add()/hide()/show()

/**
 * 以add()/hide()/show()的方式添加
 * 判断fragment是否已被添加进入fragmentManager
 * 已添加:直接显示
 * 未添加:指定布局R.id.layout_content,add
 */
private void showFragment(Fragment newFragmeent) {
        if (newFragmeent != currentFrament ) {
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            if (!newFragmeent.isAdded()) {
                 transaction
                .hide(currentFrament)
                .add(R.id.layout_content, newFragmeent)
                .commit();
            } else {
                transaction
               .hide(currentFrament)
               .show(newFragmeent)
               .commit();
            }
            currentFrament = newFragmeent
        }
}
  1. fragment 未被添加进入 fragmentManager,采用 add 的方式添加 :

触发生命周期 与 replace()的处理方式相同,选择合适生命周期即可

  1. fragment 已被添加进入 fragmentManager,采用 show 的方式:

触发 onHiddenChanged(boolean hidden) 一般无需处理加载,数据已经在 add()时通过生命周期加载过了

/**
 * show()/hide()会触发 add()不会触发
 * 此方法只是用于感知show()和hide()
 */
@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    if(hidden){
        //TODO now invisible to user
    } else {
        //TODO now visible to user
    }
}

viewpager + fragment

  • 只有在 adapter 是 FragmentPagerAdapter 或 FragmentStatePagerAdapter 才有效果

需要注意的是:
位于 FragmentPagerAdapter 或 FragmentStatePagerAdapter 当中的fragment,setUserVisibleHint(boolean isVisibleToUser)的调用时机分为两种

  1. fragment 实例化 : 所有生命周期之前
  2. fragment 只是切换显隐,但并未实例化 : 显示或隐藏的时候
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mHasCreatedView = false;
    mHasLoadedOnce = false;
    isFragmentVisible = false;
}

/**
 * 两步分别处理两个fragment
 * 1. 由不可见切换为可见的fragment
 * 2. 由可见切换为不可见的fragment
 */

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    //通过mRootView是否为null来判断是否已经初始化完成(也就是判断具体是通过哪一次触发)
    if (mRootView == null) {
        return;
    }
    //初始化完成,标记,代表是由第二种方式触发
    mHasCreatedView = true;
    //isVisibleToUser == true,表示fragment由不可见切换为可见
    if (isVisibleToUser) {
      onFragmentVisibleChange(true);
      isFragmentVisible = true;
      changeToVisiable();
      return;
    }
    //可见的fragment由可见切换为不可见
    if (isFragmentVisible) {
      onFragmentVisibleChange(false);
      isFragmentVisible = false;
    }
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ...
    //通过第一种方式触发时,并没有进行加载数据
    if (mHasCreatedView){
      return;
    }
    //进行第一种方式触发时的数据加载
    if (getUserVisibleHint()) {
       onFragmentVisibleChange(true);
       isFragmentVisible = true;
       changeToVisiable();
    }
}

private void changeToVisiable(){
  //从未加载过,则加载
  if (!mHasLoadedOnce) {
    onLazyLoad();
  }
}

/**
 * 可见性的切换触发
 *
 */
protected void onFragmentVisibleChange(boolean isvisible) {

}

/**
 * 懒加载
 */
protected void onLazyLoad() {
    //已经加载过,标记
    mHasLoadedOnce = true;
}

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