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()執行
5、需要解決的問題
5.1消除預加載(顯示界面的時候再加載數據)
5.2跳轉頁面順序,刷新數據