Android ViewPager优化
2016-12-05 02:04
302 查看
Android的ViewPager控件是我们Android App开发最常用的控件之一,本文将通过setOffscreenPageLimit增加缓存页面、setUserVisibleHint实现延迟加载、以及Adapter(FragmentPagerAdapter还是FragmentStatePagerAdapter)选择这3方面来谈谈Android ViewPager优化的一些要点。
OffscreenPageLimit默认值是1,它用于限制预加载或缓存页面的个数:
第一次载入时候,第2页的内容也会预装载;
滑到第2页时候,第3页的内容也会预装载;
滑到第3页时候,第4页的内容也会预装载,第1页被destory;
如果把OffscreenPageLimit的值改为2:
第一次载入时候,第2、3页的内容也会预装载;
滑到第2页时候,第4页的内容也会预装载;
滑到第3页时候,第5页的内容也会预装载;
滑到第4页时候,第6页的内容也会预装载,第1页被destory;
我们可以适当增加OffscreenPageLimit的值,但也不能太大,如果页面只有3-4个的话,可以考虑把全部页面都缓存起来以提高滑动的流畅性
简单地说,就是在Fragment可视性发生变化时,setUserVisibleHint就会被回调,这样的话,我们就可以在此做些文章以实现数据的延迟加载:
这样,预加载时候因mIsVisible=false而不会真正去加装数据,只有滑动到这个页面时候才会真正去加载数据;如果滑出这个页面又滑动回来,这时候adapter如果有数据的话也不会再去加载数据
如果一个Fragment不在OffscreenPageLimit范围内,那么:
FragmentPagerAdapter情况下
销毁仅仅回调destoryView,而不会回调detach和onDestory
再次创该Fragment时候,不会重新attach和onCreate
FragmentStatePagerAdapter情况下
销毁不仅回调destoryView,也会回调detach和onDestory
再次创该Fragment时候,需要重新attach和onCreate
FragmentStatePagerAdapter一般用于需要动态加载而且数据量比较大的情况,它可以减少缓存数据。
以下是Api文档对FragmentStatePagerAdapter的说明:
通过setOffscreenPageLimit增加缓存页面
关于OffscreenPageLimit,Api文档里有这么一个注释* Set the number of pages that should be retained to either side of the * current page in the view hierarchy in an idle state. Pages beyond this * limit will be recreated from the adapter when needed. * * <p>This is offered as an optimization. If you know in advance the number * of pages you will need to support or have lazy-loading mechanisms in place * on your pages, tweaking this setting can have benefits in perceived smoothness * of paging animations and interaction. If you have a small number of pages (3-4) * that you can keep active all at once, less time will be spent in layout for * newly created view subtrees as the user pages back and forth.</p> * * <p>You should keep this limit low, especially if your pages have complex layouts. * This setting defaults to 1.</p>
OffscreenPageLimit默认值是1,它用于限制预加载或缓存页面的个数:
第一次载入时候,第2页的内容也会预装载;
滑到第2页时候,第3页的内容也会预装载;
滑到第3页时候,第4页的内容也会预装载,第1页被destory;
如果把OffscreenPageLimit的值改为2:
第一次载入时候,第2、3页的内容也会预装载;
滑到第2页时候,第4页的内容也会预装载;
滑到第3页时候,第5页的内容也会预装载;
滑到第4页时候,第6页的内容也会预装载,第1页被destory;
我们可以适当增加OffscreenPageLimit的值,但也不能太大,如果页面只有3-4个的话,可以考虑把全部页面都缓存起来以提高滑动的流畅性
setUserVisibleHint实现延迟加载
如果我们增大了OffscreenPageLimit了,那如果每页的Fragment都需要加装数据(如访问网络),那每个页面预加载的页面都会加载数据。如何实现延迟加载?Fragment的setUserVisibleHint方法就派上用场。以下是setUserVisibleHint的api注释:/** * Set a hint to the system about whether this fragment's UI is currently visible * to the user. This hint defaults to true and is persistent across fragment instance * state save and restore. * * <p>An app may set this to false to indicate that the fragment's UI is * scrolled out of visibility or is otherwise not directly visible to the user. * This may be used by the system to prioritize operations such as fragment lifecycle updates * or loader ordering behavior.</p> * * <p><strong>Note:</strong> This method may be called outside of the fragment lifecycle. * and thus has no ordering guarantees with regard to fragment lifecycle method calls.</p> * * @param isVisibleToUser true if this fragment's UI is currently visible to the user (default), * false if it is not. */ public void setUserVisibleHint(boolean isVisibleToUser) { 。。。 }
简单地说,就是在Fragment可视性发生变化时,setUserVisibleHint就会被回调,这样的话,我们就可以在此做些文章以实现数据的延迟加载:
boolean mIsVisible = false; @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); mIsVisible = isVisibleToUser; if (isVisibleToUser) { lazyLoad(); } } void lazyLoad() { if (mIsVisible && mRecyclerView != null && mAdapter != null && mAdapter.getItemCount() == 0) { loadData(); } } void loadData(){ //load your data here }
这样,预加载时候因mIsVisible=false而不会真正去加装数据,只有滑动到这个页面时候才会真正去加载数据;如果滑出这个页面又滑动回来,这时候adapter如果有数据的话也不会再去加载数据
FragmentPagerAdapter还是FragmentStatePagerAdapter
FragmentStatePagerAdapter与FragmentPagerAdapter对Fragment的生命周期管理影响不同,简单地说:如果一个Fragment不在OffscreenPageLimit范围内,那么:
FragmentPagerAdapter情况下
销毁仅仅回调destoryView,而不会回调detach和onDestory
再次创该Fragment时候,不会重新attach和onCreate
FragmentStatePagerAdapter情况下
销毁不仅回调destoryView,也会回调detach和onDestory
再次创该Fragment时候,需要重新attach和onCreate
FragmentStatePagerAdapter一般用于需要动态加载而且数据量比较大的情况,它可以减少缓存数据。
以下是Api文档对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. * * <p>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.
相关文章推荐
- Android viewpager结合fragment的相关优化
- Android优化之ViewPager的懒加载
- Android ViewPager与Fragment的延时切换,取消预加载优化
- Android_性能优化ViewPager加载高清大图oom解决方案
- android viewpager fragment 优化 切换界面 延时加载
- 详解Android_性能优化之ViewPager加载成百上千高清大图oom解决方案
- android 项目学习随笔四(优化ViewPager)
- Android中Gridview和ViewPager显示图片的优化处理(1)
- Android优化之ViewPager的懒加载
- Android ViewPager实现无限循环(2.加入小圆点,优化自动和手动滑动冲突)
- Android_性能优化之ViewPager加载成百上千高清大图oom解决方案
- Android性能优化——优化viewPager
- android 项目学习随笔四(优化ViewPager)
- android不继承FragmentActivity实现ViewPager+Fragment(标签的优化)
- Android Viewpager+Fragment的懒加载优化问题
- Android中Gridview和ViewPager显示图片的优化处理(2)
- android 翻页, Viewpager 的使用及优化
- Android_性能优化之ViewPager加载成百上千高清大图oom解决方案
- android UI进阶之用ViewPager实现欢迎引导页面
- Android中如何使用ViewPager实现类似laucher左右拖动效果