viewPager和Fragment一起使用的时候需要注意Fragment的状态保存和Fragment的数据预加载问题。
- 上一篇文章我眼中的Fragment基类的写法通过创建Fragment基类解决了Fragment和ViewPager一起使用时的数据预加载问题。
- 但是仔细看我的上一篇文章中关于具体的Fragment写法中,我通过重写了setLazy()方法来加载数据,还有关键的方法就是在onCreateView方法中,我等fragment的视图创建完成后,再调用了setLazyLoad()方法,确保不会出现数据加载的时候,控件还未初始化导致程序报空指针崩溃的错误。
到这里,大家觉得我说的很正确,数据预加载确实是应该这样做啊。
- 但是如果是结合viewPager使用,当切换不同的fragment的时候,还是会调用两遍setLazy()方法。因为切换不同的fragment的时候,由于viewPager加载页面的机制,还是会存在fragment重新调用onCreate的setLazyLoad()方法,再加上重写的setLazyLoad()方法,也还是调用了两次。
- 解决方法就是,创建ViewPagerAdapter的时候,重写相关方法,不用父类的方法,自己根据当前页面显示与否调用hide和show方法来隐藏和显示fragment。这样就不会导致fragment的重复创建和销毁了,从而可以实现fragment的状态的保存。
实现代码
/**
* 创建FragmentAdapter继承FragmentPagerAdapter,并重写相关方法
*/
private class FragmentAdapter extends FragmentPagerAdapter{
public FragmentAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Fragment fragment = fragmentList.get(position);
Bundle bundle = new Bundle();
bundle.putString("id","" + position);
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getCount() {
return fragmentList.size();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// 将实例化的fragment进行显示即可。
Fragment fragment = (Fragment) super.instantiateItem(container, position);
getSupportFragmentManager().beginTransaction().show(fragment).commit();
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);// 注释父类方法
Fragment fragment = fragmentList.get(position);// 获取要销毁的fragment
getSupportFragmentManager().beginTransaction().hide(fragment).commit();// 将其隐藏即可,并不需要真正销毁,这样fragment状态就得到了保存
}
}
上面有两个方法很关键,在instantiateItem和destroyItem方法里面,我重写了自己的逻辑。实现了fragment状态的保存。
A little bit of progress every day!Come on!