使用Fragment懒加载的一种方式

easydown1 8年前
   <p>在很多应用中,首页都是由三个或四个Fragment构成,且都是上中下结构。这种设计方式大行其道,但是作为首页,每一个Fragment的内容肯定是较多的,这个时候直接加载出来,或是默认加载两三个都是有点耗费资源的,特别是在打开应用的时候,如果操作过多可能会卡,所以很多应用在首页都会使用Fragment懒加载,例如微信。</p>    <p>对于如何懒加载,也算是Android中比较简单的内容,本文只是针对这个问题提供一种比较通用的解决方法。如果你对Android开发比较熟悉的话,不要让本文浪费你的时间。如果你阅读本文,你将会学习如下内容:</p>    <ul>     <li> <p>Fragment 中 setUserVisibleHint 函数</p> </li>     <li> <p>上中下结构的首页设计实现</p> </li>     <li> <p>Fragment 懒加载的一种实现方式</p> </li>    </ul>    <h2><strong>一,创建懒加载基类Fragment</strong></h2>    <p>这个函数简单来说就是用来表明该Fragment是否向用户展示,如果用户能够看到该Fragment,那么这个函数的参数则为 true 。说起来简单,但是这个函数有个特别需要注意的地方就是 <strong>此函数不是生命周期函数</strong> 。也就是说,该方法有可能在脱离生命周期的地方调用,例如当Fragment还没有 onCreateView 时,这个函数就有可能调用,而此时如果控制界面的话,就会出现 NullPointerException 。在进行懒加载的处理时,这一点需要特别照顾。</p>    <p>在这种懒加载方式中,先创建一个LazyFragment实现懒加载的所有操作,然后再创建其子类作为实际使用。这样的话,只要是继承自这个LazyFragment的Fragment就会具有懒加载的功能,方便实际使用。</p>    <p>1. 首先,为了进行懒加载,设定几个标志:</p>    <pre>  <code class="language-java">private boolean hasLoaded = false;  //标识是否已经加载过  private boolean hasCreated = false; //标识onCreateView是否已调用  private boolean needInit = false;   //标识是否需要在onCreateView中</code></pre>    <p>2. 在 setUserVisibleHint 中进行判断处理</p>    <pre>  <code class="language-java">if (isVisibleToUser && !hasLoaded) {    //如果当前Fragment向用户展示且没有加载过,进行下一步判断      if (hasCreated) {   //如果onCreateView已经被创建,此时进行加载          initWrapper();      } else {        //如果Fragment没有创建,那么设置标记,在onCreateView中加载          needInit = true;      }  }</code></pre>    <p>此处进行的一些判断操作就是为了处理此函数在Fragment还没有创建界面时的情况。如果出现了这种情况,那么设置标记位在 onCreateView 中加载。其中 initWrapper 函数来进行加载界面,而此时加载的仅仅为该LazyFragment的界面,只包含一个 ProgressBar 和 FramentLayout 。其中 ProgressBar 仅仅为加载之前的展示,而 FramentLayout 则是用来放置其子类布局的。</p>    <pre>  <code class="language-java">private void initWrapper() {      LayoutInflater.from(getContext()).inflate(setContentView(), content);      initialize();      fadeOutView(progressBar, mShortAnimationDuration);      fadeInView(content, mShortAnimationDuration);      hasLoaded = true;  }</code></pre>    <p>3. 创建子类使用的函数</p>    <pre>  <code class="language-java">/**   * 供子类使用,子类fragment初始化操作,此函数内部真正开始进行页面的一些列操作   */  abstract void initialize();    /**   * 子类fragment设置布局,返回fragment要设定的布局   * @return 子类fragment要显示的布局   */  @LayoutRes  abstract int setContentView();</code></pre>    <p>上面基本都是创建Fragment懒加载基类重点的地方,其子类只需要复写上面两个函数就可以以懒加载的方式使用。其他内容可以使用查看项目仓库。</p>    <h2><strong>二,创建懒加载子类Fragment</strong></h2>    <p>其实只要实现了基类,那么懒加载框架就已经基本完成,继承子类只是来使用,这个地方是比创建其基类要容易很多。创建其子类只需要复写这两个函数,这样就可以作为一个普通的Fragment来使用:</p>    <pre>  <code class="language-java">@Override  void initialize() {      //用来进行本Fragment的初始化操作  }    @Override  int setContentView() {      return R.layout.fragment;   //返回本类所的布局  }</code></pre>    <h2><strong>三,创建使用懒加载Fragments的Activity</strong></h2>    <p>一般来说使用标签页的Activity,都是上中下结构,上面 Toolbar ,中间 FrameLayou 用来显示内容,下面就是 Bottom Navigation Tab。这种实现并没有什么难度,也有很多种实现方式,特别是底部导航栏。而在中间,本例子种使用的是 ViewPager ,这样可以实现左右滑动切换,也是微信的加载方式。其中代码与Fragment懒加载无关,所以就不再赘述。</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/b95349fbdf18</p>    <p> </p>