默认情况下(setOffscreenPageLimit没有调用)
FragmentPagerAdapter:保存所有加入的fragment,虽然步长超过1的页面会调用destroyItem,但是在fragment的生命周期里,只有onDestroyView调用了,没有调用onDestory,也没有调用onDetach,所以fragment只是把上面的view销毁了,fragment并没有销毁,下次再创建的时候,只会调用onCreateView和onActivityCreated,所以FragmentPagerAdapter里所有fragment都没有销毁,这样占用内存大,同时避免了频繁的销毁和创建,适用于页面比较少的情况
FragmentStatePagerAdapter:对步长以内的fragment,跟FragmentPagerAdapter一样,不会调用任何销毁操作,再次显示也无需重新创建,对步长以外的fragment会调用destroyItem,跟FragmentPagerAdapter不一样,会真正销毁(同时销毁view和fragment,调用onDestroyView以及其后面的所有销毁方法),重建时会从最初的onAttach开始一直到onActivityCreated,适用于页面比较多的情况
结合adapter的notifyDataSetChanged使用:
原来viewpager里fragment顺序为1,3,2,5秒后需要变成1,2,3,如果使用FragmentPagerAdapter,会一直保留原来的fragment,notifyDataSetChanged只能改变tab的标题,viewpager里面的fragment不会改变
package com.qf.zhouyi.fragmentstatepageradapter; import android.os.Bundle; import android.os.Handler; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; public class MyActivity extends AppCompatActivity { Handler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final List<Fragment> listFags = new ArrayList<>(); listFags.add(new FragmentOne()); listFags.add(new FragmentThree()); listFags.add(new FragmentTwo()); final List<String> lstTitles = new ArrayList<>(); lstTitles.add("1"); lstTitles.add("3"); lstTitles.add("2"); ViewPager vptest = (ViewPager) findViewById(R.id.ac_tab_vp); final PagerAdapter adapter =new Find_tab_Adapter(getSupportFragmentManager(), listFags, lstTitles); vptest.setAdapter(adapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.ac_tab_layout); //tabLayout.setTabsFromPagerAdapter(); tabLayout.setupWithViewPager(vptest); mHandler = new Handler(); mHandler.postDelayed(new Runnable() { @Override public void run() { listFags.clear(); listFags.add(new FragmentOne()); listFags.add(new FragmentTwo()); listFags.add(new FragmentThree()); lstTitles.clear(); lstTitles.add("1"); lstTitles.add("2"); lstTitles.add("3"); adapter.notifyDataSetChanged(); } }, 5000); } public class Find_tab_Adapter extends FragmentPagerAdapter { private List<Fragment> list_fragment; //fragment列表 private List<String> list_Title; //tab名的列表 public Find_tab_Adapter(FragmentManager fm, List<Fragment> list_fragment, List<String> list_Title) { super(fm); this.list_fragment = list_fragment; this.list_Title = list_Title; } @Override public Fragment getItem(int position) { return list_fragment.get(position); } @Override public int getCount() { return list_Title.size(); } //此方法用来显示tab上的名字 @Override public CharSequence getPageTitle(int position) { return list_Title.get(position % list_Title.size()); } @Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); Log.d("zy","销毁页面:"+position); } // @Override // public int getItemPosition(Object object) { // return PagerAdapter.POSITION_NONE; // } } }
如果把注释的getItemPosition写上,5s后fragment顺序变成1,3,3
当 PagerAdapter.notifyDataSetChanged() 被触发时,ViewPager.dataSetChanged() 也可以被触发。该函数将使用 getItemPosition() 的返回值来进行判断,如果为 POSITION_UNCHANGED,则什么都不做;如果为 POSITION_NONE,则调用 PagerAdapter.destroyItem() 来去掉该对象,并设置为需要刷新 (needPopulate = true) 以便触发生成新的对象
但是中间一个没有销毁,不会重新生成
如果adpter换成FragmentStatePagerAdapter,getItemPosition不返回POSITION_NONE,5s后fragment顺序也变成1,3,3,getItemPosition返回POSITION_NONE就变成正常的1,2,3了