1、添加Adapter
public class NewsFragmentPagerAdapter extends FragmentPagerAdapter {
private static final String TAG ="PagerAdapter";
private ArrayList<Fragment> fragments;
private FragmentManager fm;
private List<ChannelItem> userChannels;
private ArrayList<Boolean> fragmentsUpdateFlag=new ArrayList<>();
public NewsFragmentPagerAdapter(FragmentManager fm) {
super(fm);
this.fm = fm;
}
public NewsFragmentPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, List<ChannelItem> userChannels) {
super(fm);
this.fm = fm;
this.fragments = fragments;
initFlag();
this.userChannels =userChannels;
}
/**
* 初始化更新标志位
*/
private void initFlag() {
for (int i = 0; i < fragments.size(); i++) {
fragmentsUpdateFlag.add(false);//初始化 都不需要更新
}
}
@Override
public int getCount() {
return fragments.size();
}
/**
* @param position
* @return 艹 调用notifyDatasetChange getItem方法并没有被调用
*/
@Override
public Fragment getItem(int position) {
Log.e(TAG,"getItem()被调用:"+position);
return fragments.get(position);
}
/**
* 如果 Item 的位置如果没有发生变化,则返回 POSITION_UNCHANGED。
* 如果返回了 POSITION_NONE,表示该位置的 Item 已经不存在了。
* 默认的实现是假设 Item 的位置永远不会发生变化,而返回 POSITION_UNCHANGED,所以notifyXXXX没有起作用
* @param object
* @return
*/
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
/**
* Viewpager 的刷新过程是这样的,在每次调用 PagerAdapter 的 notifyDataSetChanged() 方法时,都会激活 getItemPosition(Object object) 方法,
* 该方法会遍历 ViewPager 的所有 Item(由缓存的 Item 数量决定,默认为当前页和其左右加起来共3页,这个可以自行设定,但是至少会缓存2页),
* 为每个 Item 返回一个状态值(POSITION_NONE/POSITION_UNCHANGED),
* 如果是 POSITION_NONE,那么该 Item 会被 destroyItem(ViewGroup container, int position, Object object) 方法 remove 掉,然后重新加载,
* 如果是 POSITION_UNCHANGED,就不会重新加载,默认是 POSITION_UNCHANGED,
* 所以如果不重写 getItemPosition(Object object),修改返回值,就无法看到 notifyDataSetChanged() 的刷新效果。
* @param currentfrags 在这里将所有的Fragment都移除了,貌似不太好吧
*/
public void setFragments(ArrayList<Fragment> currentfrags,List<ChannelItem> currentChannels) {
/**
* 这里可以确定哪些需要改变的么?
* 这里的条数 以新的Fragment为主
* */
if(currentChannels.size()>=userChannels.size()){
for (int i = 0; i < userChannels.size(); i++) {
if (userChannels.get(i).getId()==currentChannels.get(i).getId()){
fragmentsUpdateFlag.set(i, false);//如果相同 就不需要更新了
}else {
fragmentsUpdateFlag.set(i,true);//如果不同 就更新
}
}
for (int i = userChannels.size(); i < currentChannels.size(); i++) {
fragmentsUpdateFlag.add(i,true);//多出来的部分都要更新
}
}else {
//如果栏目减少了,多出来的部分就不用管了
for (int i = 0; i < currentChannels.size(); i++) {
if (userChannels.get(i).getId()==currentChannels.get(i).getId()){
fragmentsUpdateFlag.set(i,false);//如果相同 就不需要更新了
}else {
fragmentsUpdateFlag.set(i,true);//如果不同 就更新
}
}
}
//更新集合
fragments = currentfrags;
userChannels=currentChannels;
notifyDataSetChanged();
}
/**
* @param container
* @param position
* @return
*/
@Override
public Object instantiateItem(ViewGroup container, final int position) {
/*Object obj = super.instantiateItem(container, position);
return obj;*/
//得到缓存的fragment
Fragment fragment = (Fragment) super.instantiateItem(container, position);
//得到tag,这点很重要
String fragmentTag = fragment.getTag();
if (fragmentsUpdateFlag.get(position % getCount())) {
//如果这个fragment需要更新
FragmentTransaction ft = fm.beginTransaction();
//移除旧的fragment
ft.remove(fragment);
//换成新的fragment
fragment = fragments.get(position % getCount());
//添加新fragment时必须用前面获得的tag,这点很重要
ft.add(container.getId(), fragment, fragmentTag);
ft.attach(fragment);
ft.commitAllowingStateLoss();
//复位更新标志
fragmentsUpdateFlag.set(position % getCount(),false);
}
return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
return userChannels.get(position).getName();
}
2、Viewpager填充Adapter
homeViewPager = (ViewPager) view.findViewById(R.id.homepager_menu_detail);
pagerAdapter = new NewsFragmentPagerAdapter(mContext.getSupportFragmentManager(),fragments,userChannels);
homeViewPager.setAdapter(pagerAdapter);
3、填充效果
4、滑动tab页 Fragment加载顺序
从头条滑动到主题页面:
08-08 17:05:33.464 15970-15970图片的 onCreate()执行
08-08 17:05:33.464 15970-15970图片onCreateView()执行
从专题页滑动到图片页面:
08-08 17:07:08.344 15970-15970 原创的 onCreate()执行
08-08 17:07:08.344 15970-15970 原创onCreateView()执行
规律:viewPager会预加载下 一页的数据
当所有页面都create一遍后,viewpager预加载下一页只会调用onCreateView方法:
08-08 17:08:18.744 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 原创onCreateView()执行
08-08 17:08:20.184 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 图片onCreateView()执行
08-08 17:08:23.914 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 专题onCreateView()执行
08-08 17:08:26.854 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 头条onCreateView()执行
08-08 17:08:31.974 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 图片onCreateView()执行
08-08 17:08:33.984 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 原创onCreateView()执行
08-08 17:08:35.314 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 本地onCreateView()执行
08-08 17:08:38.994 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 培训onCreateView()执行