应用场景
- 我们知道,在viewpage中加载多个fragment默认会预加载1项数据。而当左右滑动切换时,如果加载的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();
}