您的位置:首页 > 移动开发 > Android开发

Android ViewPager优化

2016-12-05 02:04 302 查看
Android的ViewPager控件是我们Android App开发最常用的控件之一,本文将通过setOffscreenPageLimit增加缓存页面、setUserVisibleHint实现延迟加载、以及Adapter(FragmentPagerAdapter还是FragmentStatePagerAdapter)选择这3方面来谈谈Android ViewPager优化的一些要点。

通过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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: