ViewPager簡介:
ViewPager是android擴展包v4包中的類,這個類可以讓用戶左右切換當前的view。
1)ViewPager類直接繼承了ViewGroup類,所有它是一個容器類,可以在其中添加其他的view類。
2)ViewPager類需要一個PagerAdapter適配器類給它提供數據。
3)ViewPager經常和Fragment一起使用,並且提供了專門的FragmentPagerAdapter和FragmentStatePagerAdapter類供Fragment中的ViewPager使用。
對於PagerAdapter類,必須至少實現如下的4個方法,如果需要更好的擴展也可以實現更多的方法。
public Object instantiateItem(ViewGroup container, int position)
public void destroyItem(ViewGroup container, int position,Object object)
public int getCount()
public boolean isViewFromObject(View arg0, Object arg1)
FragmentStatePagerAdapter簡介以及其工作過程
顯然如果要實現上面的這麼幾種方法,操作起來複雜多了,Gogle提供了一個PagerAdapter的子類FragmentStatePagerAdapter來協助處理很多細節問題,以簡化操作。
使用FragmentStatePagerAdapter需要重寫他的倆個方法:
1)Fragment getItem(int position):該方法返回當前的Fragment,交給相關聯的Activity。
2)int getCount():該方法返回數組列表包含的項目數。
在PageActivity中:
...
ViewPager viewPager=(ViewPager) findViewById(R.id.activity_pager_view);
viewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
@Override
public Fragment getItem(int position) {
NoteBookItem item=mList.get(position); //mlist是當前要加載的數組列表
Log.e("PageActivity","position is: "+position);
Log.e("PageActivity","uuid is: "+item.getUUID().toString());
return PageFragment.newInstance(item.getUUID()); //返回一個PageFragment
}
@Override
public int getCount() {
return mList.size();
}
});
點擊第一項,當跳轉到PageActivity,查看打印信息:
PageActivity: position is: 1
PageActivity: uuid is: cae9e2c3-6fd1-46b1-8f76-dc6149388f93
PageActivity: position is: 0
PageActivity: uuid is: 232cc96d-eda9-4e10-a859-e3af4bcba587
PageActivity: position is: 2
PageActivity: uuid is: 1b23b9f5-79ce-4de6-9b79-011a5d96a1b3
也就是說FragmentStatePagerAdapter在此過程中創建並返回了三個Fragment,ViewPager默認加載當前屏幕上的列表項,以及左右相鄰頁面的數據,以便能流暢的滑動ViewPager。
舉個例子,如下圖:
當點擊了ListActivity列表中的Item1,跳轉到Item1對應的Fragment,這時候FragmentStatePagerAdapter的getItem(int position)方法就會被調用三次,分別返回三個Fragment給Activity,先返回的是Item1的Fragment做爲當前與用戶交互的Fragment,然後再分別去加載左右相鄰的Fragment,也就是Item0與Item2,並且他們都會緩存各自Item的信息。
FragmentStatePagerAdapter與FragmentPagerAdapter的區別:
倆種方法基本一致,唯一的區別在於:卸載不需要的fragment時,各自採用的方法不同。FragmentStatePagerAdapter會銷燬不需要的Fragment,FragmentManager中的Fragment會被徹底移除掉,而FragmentPagerAdapter不會銷燬實例,實例保存在FragmentManager中,它只是把視圖銷燬掉。
FragmentStatePagerAdapter的Fragment管理如下圖:
圖.FragmentStatePagerAdapter的Fragment管理
當滑動屏幕時(從Item1滑動到Item2),Item0的視圖以及實例都將被銷燬,同時ViewPager回去緩存Item3的Fragment(Item1的已經緩存過故不重複緩存)
FragmentPagerAdapter的Fragment管理如下圖:
同樣,當滑動時FragmentPagerAdapter只是銷燬了Item0的View視圖,實例依然保存在FragmentManager中。
另外,FragmentStatePagerAdapter可在onSaveInstanceState(Bundle)中保存fragment的Bundle信息。顯然FragmentPagerAdapter更佔用內存。