欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android之Viewpager+Fragment实现懒加载示例

程序员文章站 2023-11-29 13:44:34
我们在做应用开发的时候,一个activity里面可能会以viewpager(或其他容器)与多个fragment来组合使用。而viewpager默认会缓存三页数据,即:vie...

我们在做应用开发的时候,一个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。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。