1.原因
在開發(fā)過程中我們會遇到Viewpager嵌套Fragment的情況,這時如果每個Fragment中都含有耗時操作(如網(wǎng)絡(luò)請求等),由于Viewpager有預(yù)加載功能,此時無論Fragment是否可見,都已被創(chuàng)建。這樣會造成用戶的流量消耗、耗時等。
2.setUserVisibleHint()方法被移除
一般的做法是結(jié)合Fragment 有一個非生命周期的
setUserVisibleHint(boolean isVisibleToUser)
回調(diào)方法來完成懶加載功能,但是在
androidx.fragment.app.FragmentPagerAdapter
中此方法被移除了。下面是開發(fā)者文檔中提到的

image
3.生命周期
- 1)創(chuàng)建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; // 界面是否已創(chuàng)建完成
private boolean isVisibleToUser; // 是否對用戶可見
private boolean isDataLoaded; // 數(shù)據(jù)是否已請求, isNeedReload()返回false的時起作用
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//避免重復(fù)創(chuàng)建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再次可見時,是否重新請求數(shù)據(jù),默認(rèn)為flase則只請求一次數(shù)據(jù)
*
* @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;
}
}
}