FragmentPagerAdapter和FragmentStatePagerAdapter分析

您所在的位置:网站首页 viewpager2缓存个数 FragmentPagerAdapter和FragmentStatePagerAdapter分析

FragmentPagerAdapter和FragmentStatePagerAdapter分析

#FragmentPagerAdapter和FragmentStatePagerAdapter分析| 来源: 网络整理| 查看: 265

ViewPager和Fragment结合使用时,提供了两种PagerAdapter实现。 FragmentPagerAdapter和FragmentStatePagerAdapter。

一、我们先来看下Google对其注释。 FragmentPagerAdapter /** * Implementation of {@link PagerAdapter} that * represents each page as a {@link Fragment} that is persistently * kept in the fragment manager as long as the user can return to the page. * *

This version of the pager is best for use when there are a handful of * typically more static fragments to be paged through, such as a set of tabs. * The fragment of each page the user visits will be kept in memory, though its * view hierarchy may be destroyed when not visible. This can result in using * a significant amount of memory since fragment instances can hold on to an * arbitrary amount of state. For larger sets of pages, consider * {@link FragmentStatePagerAdapter}. */ /** * PagerAdapter的具体实现,每个页面(Fragment)都持久保存在Fragment Manager中,以便用户返回 * 最好用在少数静态Fragments的场景,用户访问过的Fragment都会缓存在内存中,即使其视图层次不可见而被释放(onDestroyView) * 因为Fragment可能保存大量状态,因此这可能会导致使用大量内存。 * 页面很多时,可以考虑FragmentStatePagerAdapter */ 复制代码FragmentStatePagerAdapter /** * Implementation of {@link PagerAdapter} that * uses a {@link Fragment} to manage each page. This class also handles * saving and restoring of fragment's state. * *

This version of the pager is more useful when there are a large number * of pages, working more like a list view. When pages are not visible to * the user, their entire fragment may be destroyed, only keeping the saved * state of that fragment. This allows the pager to hold on to much less * memory associated with each visited page as compared to * {@link FragmentPagerAdapter} at the cost of potentially more overhead when * switching between pages. */ /** * PagerAdapter的具体实现,也处理保存和恢复Fragment的状态数据 * 这个版本在大量页面时更有用,比如列表。 * 当页面不可见时,整个Fragment可能会被销毁(onDestroy),只保存Fragment的状态 * 可以持有少的内存来达到切换更多页面的场景 * */ 复制代码二、Adapter的初始化和销毁

下面通过分析源码,来验证下,是如何实现上面Google的注释的。

1. 初始化

ViewPager初始化时,会调用PagerAdapter的instantiateItem方法。

FragmentPagerAdapter public Object instantiateItem(@NonNull ViewGroup container, int position) { if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } final long itemId = getItemId(position); // Do we already have this fragment? String name = makeFragmentName(container.getId(), itemId); // 直接从FragmentManager中获取,即从缓存中获取 Fragment fragment = mFragmentManager.findFragmentByTag(name); if (fragment != null) { if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment); mCurTransaction.attach(fragment); } else { // 调用getItem创建新的Fragment fragment = getItem(position); if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment); mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId)); } if (fragment != mCurrentPrimaryItem) { fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); } return fragment; } 复制代码FragmentStatePagerAdapter public Object instantiateItem(@NonNull ViewGroup container, int position) { // If we already have this item instantiated, there is nothing // to do. This can happen when we are restoring the entire pager // from its saved state, where the fragment manager has already // taken care of restoring the fragments we previously had instantiated. // 先从缓存列表中获取 if (mFragments.size() > position) { Fragment f = mFragments.get(position); if (f != null) { return f; } } if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } // 缓存列表没有,则直接创建 Fragment fragment = getItem(position); if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment); // 恢复保存的State数据 if (mSavedState.size() > position) { Fragment.SavedState fss = mSavedState.get(position); if (fss != null) { fragment.setInitialSavedState(fss); } } while (mFragments.size() onCreateView->onActivityCreate->onResume。

所以如果在上面的生命周期中处理页面逻辑(比如网络请求),那么可能在页面不可见时就进行了处理。

因此,需要判断Fragment的可见,在可见时加载。就用到setUserVisibleHint。

不过该方法会先于onAttach之前,所以具体实现时需要判断下其他生命周期情况。

注意:setUserVisibleHint是在PagerAdapter类中初始化和滚动时调用的,所以需要配合ViewPager才能使用。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3