ViewPager是一个负责翻页的ViewGroup,需和PagerAdapter配合数据绑定以及生成最终的View
PageAdapter,FragmentPagerAdapter,FragmentStatePagerAdapter之间的区别,需分情况使用这三个adapter
PagerAdapter:当所要展示的视图比较简单时适用
FragmentPagerAdapter:当所要展示的视图是Fragment,并且数量比较少时适用,会缓存所有Fragment,适用于相对静态的页
FragmentStatePagerAdapter:当所要展示的视图是Fragment,并且数量比较多时适用,适用于需要处理有很多页,并且数据动态性较大、占用内存较多的情况
PagerAdapter
1、PagerAdapter是FragmentPagerAdapter和FragmentStatePagerAdapter的基类
2、若需展示自定义view(非fragment),至少继承并重写它的如下方法
instantiateItem(ViewGroup, int)
用来inflate view from xml并添加到ViewGroup(是ViewPager的引用)中,在每次ViewPager需要一个用以显示的Object的时候,该函数都会被调用12345678910111213141516public Object instantiateItem(ViewGroup container, int position) {// Inflate a new layout from our resourcesView view = mLayoutInflater.inflate(R.layout.photo_layout, container, false);// Retrieve a TextView from the inflated View, and update it's textTextView titleTextView = (TextView) view.findViewById(R.id.title);Utils.DummyItem dummyItem = mDummyItems.get(position);titleTextView.setText(dummyItem.getImageTitle());ImageView imageView = (ImageView) view.findViewById(R.id.image);ImageLoaderUtil.downloadImage(dummyItem.getImageUrl(), imageView);view.setTag(dummyItem);// Add the newly created View to the ViewPagercontainer.addView(view);// Return the Viewreturn view;}destroyItem(ViewGroup, int, Object)
PagerAdapter默认缓存3个子项(当前view及前一个和后一个子项),当滑动时其它销毁的子项会调用destroyItem123456789/*** Destroy the item from the {@link android.support.v4.view.ViewPager}. In our case this is simply removing the* {@link View}.*/public void destroyItem(ViewGroup container, int position, Object object) {container.removeView((View) object);Log.i(TAG, "destroyItem() [position: " + position + "]" + " childCount:" + container.getChildCount());}getCount()
1234public int getCount() {return (null == mLists ? 0 : mLists.size());}isViewFromObject(View, Object)
12345678/*** @return true if the value returned from {@link #instantiateItem(ViewGroup, int)} is the* same object as the {@link View} added to the {@link android.support.v4.view.ViewPager}.*/public boolean isViewFromObject(View view, Object object) {return object == view;}
FragmentPagerAdapter
1、会缓存所有Fragment,一旦一个fragment被创建,就不会被销毁,被销毁的只是fragment的视图层次,它会被FragmentManager保存起来。
fragment第一次被创建时,依次执行onAttach(), onCreate(), onCreateView(), onViewCreated(), onActivityCreated(), onViewStateRestored(), onStart(), onResume()
fragment不在屏幕显示时,依次执行onPause(), onStop(), onDestroyView(),并用于不会执行onDestroy()和onDetach()
fragment再次显示时,会从FragmentManager中获取,依次执行onCreateView(), onViewCreated(), onActivityCreated(), onViewStateRestored(), onStart(), onResume()
ps:当ViewPager设置了setOffscreenPageLimit()生命周期根据具体情况而定
2、至少需实现getItem()及getCount()
- getItem()
instantiateItem()函数中判断一下要生成的 Fragment 是否已经生成过了,如果生成过了,就使用旧的,旧的将被 Fragment.attach();如果没有,就调用 getItem() 生成一个新的,新的对象将被 FragmentTransation.add()。
如果需要向 Fragment 对象传递相对静态的数据时,一般通过 Fragment.setArguments() ,这部分代码应当放到 getItem()。它们只会在新生成 Fragment 对象时执行一遍。
如果需要在生成 Fragment 对象后,将数据集里面一些动态的数据传递给该 Fragment,那么这部分代码不适合放到 getItem() 中,这部分代码应该放到这个函数的重载里。因为当数据集发生变化时,往往对应的 Fragment 已经生成,如果传递数据部分代码放到了 getItem() 中,这部分代码将不会被调用。这也是为什么调用 PagerAdapter.notifyDataSetChanged() 后,getItem() 没有被调用的一个原因。
FragmentStatePagerAdapter
1、与FragmentPagerAdapter不同的地方在于,当Fragment离开视线时则被消除。
2、调用destroyItem()函数,将 Fragment 移除,即调用 FragmentTransaction.remove(),并释放其资源。
BaseFragment封装
根据项目需求,以下封装了一个Fragment基类,包含加载一次数据的函数loadOnceData(),可设置BaseFragment子类的isLoadedOnce = false;来重置loadOnceData()数据重新加载一次