Android之Viewpager+Fragment实现懒加载示例
我们在做应用开发的时候,一个activity里面可能会以viewpager(或其他容器)与多个fragment来组合使用。而viewpager默认会缓存三页数据,即:viewpager每加载一个fragment,都会预先加载此fragment左侧或右侧的fragment。而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在这个activity刚创建的时候就变成需要初始化大量资源,浪费用户流量不止,还造成卡顿,这样的结果,我们当然不会满意。那么,能不能做到当切换到这个fragment的时候,它才去初始化呢?答案就在fragment里的setuservisiblehint这个方法里。
该方法用于告诉系统,这个fragment的ui是否是可见的。所以我们只需要继承fragment并重写该方法,即可实现在fragment可见时才进行数据加载操作,即fragment的懒加载。
代码如下:
package com.yctime.truelove.fragment; import android.content.context; import android.nfc.tag; import android.os.bundle; import android.support.annotation.nullable; import android.support.v4.app.fragment; import android.util.log; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; /** * 基类fragment */ public abstract class basefragment extends fragment { protected view mrootview; public context mcontext; protected boolean isvisible; private boolean isprepared; private boolean isfirst = true; public basefragment() { // required empty public constructor } @override public void setuservisiblehint(boolean isvisibletouser) { super.setuservisiblehint(isvisibletouser); // log.d("tag", "fragment->setuservisiblehint"); if (getuservisiblehint()) { isvisible = true; lazyload(); } else { isvisible = false; oninvisible(); } } @override public void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); mcontext = getactivity(); sethasoptionsmenu(true); // log.d("tag", "fragment->oncreate"); } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { if (mrootview == null) { mrootview = initview(); } // log.d("tag", "fragment->oncreateview"); return mrootview; } @override public void onactivitycreated(@nullable bundle savedinstancestate) { super.onactivitycreated(savedinstancestate); // log.d("tag", "fragment->onactivitycreated"); isprepared = true; lazyload(); } protected void lazyload() { if (!isprepared || !isvisible || !isfirst) { return; } log.d("tag", getclass().getname() + "->initdata()"); initdata(); isfirst = false; } //do something protected void oninvisible() { } public abstract view initview(); public abstract void initdata(); }
为了可复用,这里我新建了个basefragment,在basefragment,我增加了三个方法,一个是onvisiable,即fragment被设置为可见时调用,一个是oninvisible,即fragment被设置为不可见时调用。另外再写了一个lazyload的抽象方法,该方法在onvisible里面调用。
注意看这个方法:
protected void lazyload() { if (!isprepared || !isvisible || !isfirst) { return; } log.d("tag", getclass().getname() + "->initdata()"); initdata(); isfirst = false; }
这里我们做了三个判断,判断isprepared和isvisible和isfirst只有全为true,才去执行initdata()方法加载网络(或本地)数据。
①isprepared参数在系统调用onactivitycreated时设置为true,这时oncreateview方法已调用完毕(一般我们在这方法里执行findviewbyid等方法),确保 initdata()方法不会报空指针异常。
②isvisible参数在fragment可见时通过系统回调setuservisibilehint方法设置为true,不可见时为false,这是fragment实现懒加载的关键。
③isfirst确保viewpager来回切换时basefragment的initdata方法不会被重复调用,initdata在该fragment的整个生命周期只调用一次,第一次调用initdata()方法后马上执行 isfirst = false。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。