Viewpager与fragment的组合在项目中使用的频率过高,咱们对Viewpager的两种的Adapter的处理方式略显不足增强一下认识。缓存
先简单看看Fragment的两种Adapter的使用方式。
都是PagerAdapter的子类。 bash
1:FragmentStatePagerAdapter
2:FragmentPagerAdapter复制代码
当Viewpager.setAdapter(),Viewpager与PagerAdapter创建双向的联系。
1)Viewpager会拥有pagerAdapter的对象,能getAdapter获取到当前的Adapter。
2)mAdapter.setViewPagerObserver(new PagerObserver),至此获得adapter中的注册测,能向Viewpager传递数据。这样就算绑在一块儿了。
ide
这是咱们经常使用两种Adapter的基类。这是一个abstract的,直接继承他的话我么须要重写方法
1)getItemPosition();
//instantiateItem()的返回值将有此函数的返回值进行判断,是否进行调用。函数
public static final int POSITION_UNCHANGED = -1;
public static final int POSITION_NONE = -2;复制代码
如若不重写,默认返回POSITION_UNCHANGED,将不会调用Viewpager的observer.notifit()
所以,调用Adapter.notifyDataSetChanged()将不会出现什么改变。
布局
/**ui
/**spa
if(rootView==null){
rootView=inflater.inflate(R.layout.tab_fragment, null);
}
//缓存的rootView须要判断是否已经被加过parent, 若是有parent须要从parent删除,要否则会发生这个rootview已经有parent的错误。
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null) {
parent.removeView(rootView);
} 复制代码
这里重点说明一下:setUserVisibleHint 调用 在全部生命周期以前执行。每次Adapter切换都会调用相应的Fragment的此方法。
思路也就来了。 实现的思路不少种,仔细看这个生命周期,总结规律,这个懒加载也就现实了。3d
`public abstract class LazzyFragment extends Fragment {
//判断控件是否加载完毕
private boolean isCreateView = false;
//判断是否已加载过数据
public boolean isLoadData = false;
/**
* 返回layoutView
* @param inflater
* @param container
* @return 初始化布局文件
*/
public abstract View getView(LayoutInflater inflater, ViewGroup container);
/**
* 初始化控件
*/
public abstract void initViews(View view);
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = getView(inflater, container);
initViews(view);
isCreateView = true;
return view;
}
//注意,此方法再全部生命周期以前调用,不可操做控件
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && isCreateView && !isLoadData) {
loadData();
}
}
/**
* 加载数据
*/
public void loadData() {
//若是没有加载过就加载,不然就再也不加载了
if (!isLoadData) {
//加载数据操做
isLoadData = true;
}
}
// 第一次进入ViewPager的时候咱们须要直接加载,由于此时setUserVisibleHint 已经调用过了。
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getUserVisibleHint())
loadData();
}复制代码
}`code