解决viewpager和fragment一起使用时,fragment会被预加载的问题
预加载无法真正的解决,我们只能做到懒加载,懒加载即在fragment可视化的时候去加载需要的数据。而使用懒加载的时候需注意setUserVisibleHint方法,此方法只有fragment可视化的时候,才会调用。
setUserVisibleHint有false和true两个值,false表示该fragment对用户不可见,true便是该fragment对用户可见。
但要注意的是,setUserVisibleHint方法只适用于viewpager和fragment组合使用,只加载单个fragment时,是不会调用此方法的。
且只有viewpager中fragment切换到fragment,fragment才会调用setUserVisibleHint,如果此时加载fragment的activity被别的activity覆盖时,或者是销毁时,都不会让fragment调用setUserVisibleHint
例:fragment一共有四个,fragmentA,fragmentB,fragmentC,fragmentD
当进入fragmentA时,打印出来的fragment生命周期为
setUserVisibleHint **true** (fragmentA)-->onCreateView(fragmentA)-->onActivityCreated(fragmentA)-->onCreateView(fragmentB)-->onActivityCreated(fragmentB)
当由fragmentA切换到fragmentB时,打印出来的fragment生命周期为
setUserVisibleHint **false** (fragmentA)-->setUserVisibleHint **true** (fragmentB)-->onCreateView(fragmentC)-->onActivityCreated(fragmentC)
由上我们可以知道,当我们进入viewpager的第一个fragment时,先调用的setUserVisibleHint方法,然后执行的生命周期;从第二个界面开始,fragment会先预加载,只有再可视化的时候才会调用setUserVisibleHint;且在切换到第二个fragment时,第一个fragment被隐藏时,也会调用setUserVisibleHint。
所以,要做到懒加载需要判断两个数据,一、当前界面是否可见;二、界面是否已经被加载。
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import butterknife.ButterKnife;
/**
* viewpager 和 fragment 懒加载
*/
public abstract class BaseFragment extends Fragment {
private boolean isViewCreated;
private boolean isLoadDateCompleted;
private boolean isDestoryDate;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(getLayout(), container, false);
ButterKnife.bind(this, view);
isViewCreated = true;
return view;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && isViewCreated && !isLoadDateCompleted) { //当进入页面 且没有加载过数据的时候
isLoadDateCompleted = true;
LoadDate();
} else if (!isVisibleToUser && isLoadDateCompleted && !isDestoryDate) { //当进入过页面 且准备离开页面时 --只适用于fragment之间来回切换
isDestoryDate = true;
destoryDate();
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//当进入页面 且没有加载过数据
if (getUserVisibleHint()) {
isLoadDateCompleted = true;
LoadDate();
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
//当退出fragment时,不走setUserVisibleHint
if (isLoadDateCompleted && !isDestoryDate) {
isDestoryDate = true;
destoryDate();
}
}
protected abstract void LoadDate();
protected abstract int getLayout();
protected abstract void destoryDate();
}