优雅地刷新RecyclerView

RafaelBroad 7年前
   <h2>前言</h2>    <p>还是那句话,RecyclerView的viewType增多,逻辑变复杂,几个月后,你确定还能理清思路吗?假设我们服务端是多个接口返回数据,你确定能正确刷新相应type吗?想一个RecyclerView高效快捷管理整个界面吗?你还在使用notifyDataSetChanged无脑刷新吗?你想单个viewType在loadingView,dataView,errorView自如切换吗?如果你迟疑了,那你不妨试试本库。</p>    <h2>特点</h2>    <ul>     <li>与Adapter为组合关系,可配合大多数Adapter</li>     <li>一行代码刷新相应viewType</li>     <li>支持非死book的shimmer加载效果</li>     <li>支持粘性头</li>     <li>支持异步刷新,可扩展(如配合RxAndroid)</li>     <li>支持加载相应type错误页面</li>     <li>支持高频率刷新(流畅,异步执行)</li>    </ul>    <h2>效果</h2>    <h3>线性排布</h3>    <p><img src="https://simg.open-open.com/show/c3a66ecc775fbbb380d7c59f501460a5.gif"></p>    <h3>方格排布</h3>    <p><img src="https://simg.open-open.com/show/e88c7f43930c46f39a9abb8e4fb252c7.gif"></p>    <h3>关键字高亮</h3>    <p><img src="https://simg.open-open.com/show/a0480696ccbef66f4a7f7336343c3cc0.gif"></p>    <h3>刷新错误页面</h3>    <p><img src="https://simg.open-open.com/show/19cce7be04e5811cdde0f496f808ec69.gif"></p>    <h3>高频率刷新</h3>    <p><img src="https://simg.open-open.com/show/7ffe42cceec3b3c113c8bfa14fc30861.gif"></p>    <h2>更新内容</h2>    <ul>     <li>支持刷新type错误页面(可自定义)</li>     <li>支持同时刷新多个type(异步,高频率)</li>     <li>链式注册资源</li>     <li>支持刷新单个数据</li>     <li>提供helper的清除单个type,清除整个界面api</li>     <li>提供getHeaderId的默认实现抽象类</li>    </ul>    <h3>支持刷新type错误页面(可自定义)</h3>    <pre>  <code class="language-java">public void notifyMoudleErrorChanged(ErrorEntity errorData, int type);    public void notifyMoudleErrorChanged(int type);</code></pre>    <p>一行代码搞定,前者提供实体类是考虑有些用户需要根据实体数据属性去更新,因此错误页面的layoutId是用户提供的。</p>    <h3>支持同时刷新多个type(异步,高频率)</h3>    <pre>  <code class="language-java">//刷新队列,支持高频率刷新  private Queue<HandleBase<T>> mRefreshQueue;</code></pre>    <p>这里采用的是队列的形式管理刷新,提供清空队列的Api。</p>    <h3>链式注册资源</h3>    <pre>  <code class="language-java">registerMoudle(@IntRange(from = 0, to = 999) int type)                  .level(@IntRange(from = 0) int level)                  .layoutResId(@LayoutRes int layoutResId)                  .headerResId(@LayoutRes int headerResId)                  .loading()                  .loadingLayoutResId(@LayoutRes int loadingLayoutResId)                  .loadingHeaderResId(@LayoutRes int loadingHeaderResId)                  .error()                  .errorLayoutResId(@LayoutRes int errorLayoutResId)                  .register();</code></pre>    <p>由于参数越来越多,这里采用了较为流行的链式注册,内部通过ResourcesManager管理所有资源。</p>    <p>注:原来的注册方式已设置为过时,请及时更新,不出2个版本将移除。</p>    <h3>支持刷新单个数据</h3>    <pre>  <code class="language-java">public void notifyMoudleDataAndHeaderChanged(T data, T header, int type)</code></pre>    <p>可能某个type只有一个实体数据管理着整个type</p>    <pre>  <code class="language-java">public void notifyMoudleDataAndHeaderChanged(List<? extends T> data, T header, int type)</code></pre>    <p>可传T的子类集合</p>    <h3>提供helper的清除单个type,清除整个界面api</h3>    <pre>  <code class="language-java">/**   * 清除单个type数据   *   * @param type 数据类型   */  public void clearMoudle(int type);    /**   * 清除所有数据   */  public void clear();</code></pre>    <h3>提供getHeaderId的默认实现抽象类</h3>    <p>假设你不实现粘性头而强制要写getHeaderId确实挺讨厌的,由于现在android还不是很好地兼容java8,因此暂时提供DefaultMultiHeaderEntity。</p>    <h3>使用注意点</h3>    <p>type 取值范围</p>    <ul>     <li>数据类型 [0,1000)</li>     <li>头类型 [-1000,0)</li>     <li>shimmer数据类型 [-2000,-1000)</li>     <li>shimmer头类型 [-3000,-2000)</li>     <li>error类型 [-4000,-3000)</li>    </ul>    <p>常量差值</p>    <pre>  <code class="language-java">//头类型差值  public static final int HEADER_TYPE_DIFFER = 1000;  //shimmer数据类型差值  public static final int SHIMMER_DATA_TYPE_DIFFER = 2000;  //shimmer头类型差值  public static final int SHIMMER_HEADER_TYPE_DIFFER = 3000;  //错误类型差值  public static final int ERROR_TYPE_DIFFER = 4000;</code></pre>    <h2>结束</h2>    <p>库多多少少也更新几个版本了,你的意见,你的建议,你的star,你的分享,一直是我前进的动力。还有一点要说的就是现在关于LayoutManager,RecyclerView,Adapter的流派很多,我们更关注于数据的优雅刷新。</p>    <p>如果对本库还不是很了解的同学可以到我的github查看更多版本进行了解。</p>    <h2>gradle依赖</h2>    <pre>  <code class="language-java">compile 'com.crazysunj:multitypeadapter:1.3.0'</code></pre>    <p> </p>