Android ViewPager+Fragmentt预加载 懒加载

懒加载介绍

所谓的懒加载,其实也就是延迟加载,就是等到该页面的UI展示给用户时,再加载该页面的数据(从网络、数据库等),而不是依靠ViewPager预加载机制提前加载两三个,甚至更多页面的数据.这样可以提高所属Activity的初始化速度,也可以为用户节省流量.而这种懒加载的方式也已经/正在被诸多APP所采用.

但是通过ViewPager方法setOffscreenPageLimit(int limit)的源码可以发现,ViewPager通过一定的逻辑判断来确保至少会预加载左右两侧相邻的1个页面,也就是说无法通过简单的配置做到懒加载的效果.

 
Fragment为我们提供了一个方法setUserVisibleHint(boolean isVisibleToUser),其中的参数isVisibleToUser就是表示该Fragment的UI对于用户是否可见
 

基于以上原因,我们进行数据懒加载的时机需要满足两个条件

  1. onCreateView()方法执行完毕
  2. setUserVisibleHint(boolean isVisibleToUser)方法返回true


所以在BaseFragment中用两个布尔型标记来记录这两个条件的状态.只有同时满足了,才能加载数据
<span style="color:#000000"><span style="color:#cccccc"><code class="language-java"><span style="color:#999999">//Fragment的View加载完毕的标记</span>
<span style="color:#cc99cd">private</span> <span style="color:#cc99cd">boolean</span> isViewCreated;

<span style="color:#999999">//Fragment对用户可见的标记</span>
<span style="color:#cc99cd">private</span> <span style="color:#cc99cd">boolean</span> isUIVisible;</code></span></span>
第一步,改变isViewCreated标记
 
<span style="color:#000000"><span style="color:#cccccc"><code class="language-java">@Override
<span style="color:#cc99cd">public</span> <span style="color:#cc99cd">void</span> <span style="color:#f08d49">onViewCreated</span>(<span style="color:#f8c555">View</span> view, @Nullable <span style="color:#f8c555">Bundle</span> savedInstanceState) {
    <span style="color:#cc99cd">super</span>.<span style="color:#f08d49">onViewCreated</span>(view, savedInstanceState);
    isViewCreated <span style="color:#67cdcc">=</span> <span style="color:#f08d49">true</span>;
    <span style="color:#f08d49">lazyLoad</span>();
}</code></span></span>
第二步,改变isUIVisible标记
 
<span style="color:#000000"><span style="color:#cccccc"><code class="language-java">@Override
<span style="color:#cc99cd">public</span> <span style="color:#cc99cd">void</span> <span style="color:#f08d49">setUserVisibleHint</span>(<span style="color:#cc99cd">boolean</span> isVisibleToUser) {
    <span style="color:#cc99cd">super</span>.<span style="color:#f08d49">setUserVisibleHint</span>(isVisibleToUser);
    <span style="color:#999999">//isVisibleToUser这个boolean值表示:该Fragment的UI 用户是否可见</span>
    <span style="color:#cc99cd">if</span> (isVisibleToUser) {
        isUIVisible <span style="color:#67cdcc">=</span> <span style="color:#f08d49">true</span>;
        <span style="color:#f08d49">lazyLoad</span>();
    } <span style="color:#cc99cd">else</span> {
        isUIVisible <span style="color:#67cdcc">=</span> <span style="color:#f08d49">false</span>;
    }
}</code></span></span>
第三步: 在lazyLoad()方法中进行双重标记判断,通过后即可进行数据加载
 
<span style="color:#000000"><span style="color:#cccccc"><code class="language-cpp"><span style="color:#cc99cd">private</span> <span style="color:#cc99cd">void</span> <span style="color:#f08d49">lazyLoad</span>() {
    <span style="color:#999999">//这里进行双重标记判断,是因为setUserVisibleHint会多次回调,并且会在onCreateView执行前回调,必须确保onCreateView加载完毕且页面可见,才加载数据</span>
    <span style="color:#cc99cd">if</span> (isViewCreated <span style="color:#67cdcc">&&</span> isUIVisible) {
        <span style="color:#f08d49">loadData</span>();
        <span style="color:#999999">//数据加载完毕,恢复标记,防止重复加载</span>
        isViewCreated <span style="color:#67cdcc">=</span> <span style="color:#f08d49">false</span>;
        isUIVisible <span style="color:#67cdcc">=</span> <span style="color:#f08d49">false</span>;

        <span style="color:#f08d49">printLog</span>(mTextviewContent<span style="color:#67cdcc">+</span><span style="color:#7ec699">"可见,加载数据"</span>);
    }
}</code></span></span>
第四步:定义抽象方法loadData(),具体加载数据的工作,交给子类去完成
<span style="color:#000000"><span style="color:#cccccc"><code class="language-csharp"><span style="color:#cc99cd">protected</span> <span style="color:#cc99cd">abstract</span> <span style="color:#cc99cd">void</span> <span style="color:#f08d49">loadData</span>();</code></span></span>
 
遇到的问题
1.如果tab第一次加载不是从0开始,从其他开始,会发现,第0个fragment会优先加载,导致多加载了一次
2.偶现出现加载都顺序不对的问题和加载都次数
3.Fragmnet都创建和销毁的过程和他们之间的生命周期
同样都思路
 
 
 
 
 
 

Android ViewPager中Fragment的生命周期&FragmentPageAdapter与FragmentStatePageAdapter对其的影响

  • ViewPager使用细节,如何设置成每次只初始化当前的Fragment,其他的不初始化
 

相似点:

他们都无法保存视图,即在offScreenLimit之外的Fragment总是要被destroyView。

不同点:

最大的区别就是对于在offScreenLimit之外的Fragment,FragmentPagerAdapter会销毁试图,但Fragmnet不会detach,也就是Fragment还是在内存中的,当需要再次显示时他会createView,这意味着我们可以在Fragment对象中保存一些我们需要存储的信息,createView的时候做自己的选择。

而FragmentStatePagerAdapter就不同了,相同的情况下对于在offScreenLimit之外的Fragment,被destroyView只有还有detach,也就是此前的Fragment对象不复存在了,那么我们肯定不能在Fragment中保存必要的信息了,此时可以重写onSaveInstanceState来保存必要信息,并在onCreateView的时候重新拿出来用。FragmentStatePagerAdapter中为我们保存这些state是通过一个ArrayList来实现的,意味着他是记着Fragment的index作为key来保存或者取出的,



那么对于我们开发者来说,可以在此做个选择。在使用Viewpager中Fragment页面较少的情况可以选择FragmentPagerAdapter,这样代码会少几行,简单。
 
 
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值