Android开源:SmartRefreshLayout-智能下拉刷新框架

lillc369 7年前
   <p> 正如名字所说,这是一个“聪明的下拉刷新布局”,由于它的聪明,他不只是如其他的刷新布局所说的支持所有的View,还支持多层嵌套的视图结构,下文会对这个详细说明。</p>    <p>  除了“聪明”之外,SmartRefreshLayout还具备了很多的特点。它继承至ViewGroup 而不是其他的Layout,提高了性能。</p>    <p>  吸取了现在流行的各种刷新布局的优点,包括谷歌官方的 SwipeRefreshLayout,现在非常流行的 <a href="/misc/goto?guid=4959720147803155620">TwinklingRefreshLayout</a> 、<a href="/misc/goto?guid=4958864078206473805">android-Ultra-Pull-To-Refresh</a>。还集成了各种炫酷的 Header 和 Footer。</p>    <p>  下面列出了SmartRefreshLayout所有的特点功能:</p>    <ul>     <li>支持所有的 View(AbsListView、RecyclerView、WebView....View) 和多层嵌套的 Layout(详细)</li>     <li>支持自定义并且已经集成了很多炫酷的 Header 和 Footer (图).</li>     <li>支持和ListView的同步滚动 和 RecyclerView、AppBarLayout、CoordinatorLayout 的嵌套滚动 NestedScrolling.</li>     <li>支持在Android Studio Xml 编辑器中预览 效果(图)</li>     <li>支持分别在 Default(默认)、Xml、JavaCode、中设置 Header 和 Footer.</li>     <li>支持自动刷新、自动上拉加载(自动检测列表滚动到底部,而不用手动上拉).</li>     <li>支持通用的刷新监听器 OnRefreshListener 和更详细的滚动监听 OnMultiPurposeListener.</li>     <li>支持自定义回弹动画的插值器,实现各种炫酷的动画效果.</li>     <li>支持设置主题来适配任何场景的App,不会出现炫酷但很尴尬的情况.</li>     <li>支持设置多种滑动方式来适配各种效果的Header和Footer:位置平移、尺寸拉伸、背后固定、顶层固定、全屏</li>     <li>支持内容尺寸自适应 Content-wrap_content</li>     <li>支持继承重写和扩展功能,内部实现没有 private 方法和字段,继承之后都可以重写覆盖</li>     <li>支持越界回弹(Listview、RecyclerView、ScrollView、WebView...View)  </li>    </ul>    <h2>Demo</h2>    <p><a href="/misc/goto?guid=4959750351343026679">下载 APK-Demo</a></p>    <h2>项目演示</h2>    <p><img src="https://simg.open-open.com/show/6ba804f57160cf493ba6877626c0c1a8.gif"> <img src="https://simg.open-open.com/show/44ab2cd9f306775e5d64cdc56fa9070a.gif"></p>    <p><img src="https://simg.open-open.com/show/e33b55112f3725d69914dd3b7fb67127.gif"> <img src="https://simg.open-open.com/show/c0697d35129b965d706121706e62cd29.gif"></p>    <h3>风格演示</h3>    <p><img src="https://simg.open-open.com/show/b444fd703d17a24f239bea2238a65170.gif"> <img src="https://simg.open-open.com/show/4bbe6b588e61a3f7dd85cf277d1b8fb9.gif"></p>    <p>上面这两个是我自己实现的Header,设计来自下面两个网址:<a href="/misc/goto?guid=4959750351436794172">Refresh-your-delivery</a>,<a href="/misc/goto?guid=4959750351542745053">Dropbox-Refresh</a></p>    <p>下面的Header是我把github上其他优秀的Header进行的整理和集合还有优化:</p>    <p><img src="https://simg.open-open.com/show/314cd39db2a7be13ca6d10c56cff74f4.gif"> <img src="https://simg.open-open.com/show/995781eb516f6ade533a3fc68f04cb9e.gif"></p>    <p>整理来自:<a href="/misc/goto?guid=4959750351622447258">TwinklingRefreshLayout</a>,<a href="/misc/goto?guid=4959639913144177373">Pull Down To Refresh</a></p>    <p><a href="/misc/goto?guid=4959750351750500448"><img alt="Android开源:SmartRefreshLayout-智能下拉刷新框架" src="https://simg.open-open.com/show/e45d12d86d8997fd77f312734736ace4.gif" width="300" height="533"></a></p>    <p><img src="https://simg.open-open.com/show/58ed3b665e2a6ed3b21be09f4972649b.gif"> <img src="https://simg.open-open.com/show/6052db53ea7a4adeffb01d67426df095.gif"></p>    <p>整理来自:<a href="/misc/goto?guid=4958974933812893739">FlyRefresh</a>,<a href="/misc/goto?guid=4959750351861848071">ClassicsHeader</a></p>    <p><img src="https://simg.open-open.com/show/72e706e371dc2f39c54309f134fa0d9b.gif"> <img src="https://simg.open-open.com/show/5c83bd346854cbea50d1a0abb9277012.gif"></p>    <p>整理来自:<a href="/misc/goto?guid=4959734115913699491">FunGame/BattleCity</a>,<a href="/misc/goto?guid=4959734115913699491">FunGame/HitBlock</a></p>    <p><img src="https://simg.open-open.com/show/1216ad4612f8b0500c2eee39a24998fd.gif"> <img src="https://simg.open-open.com/show/c37d2fd631c7c1ed631d0288e97923f8.gif"></p>    <p>整理来自:<a href="/misc/goto?guid=4958964899746374282">WaveSwipeRefreshLayout</a>,<a href="/misc/goto?guid=4959750351861848071">MaterialHeader</a></p>    <p><img src="https://simg.open-open.com/show/9e1c057f0144a98c52e3959cacc11391.gif"> <img src="https://simg.open-open.com/show/9f16675c9ae5618f2028a2b171aabe68.gif"></p>    <p><img src="https://simg.open-open.com/show/9208fd277707216952125ade1c1861e3.gif"> <img src="https://simg.open-open.com/show/99004f8e5f2e9ca48046a7ac9237039e.gif"></p>    <h2>框架</h2>    <p>如果你看完了效果图,或许框架的意思应该有所了解了~~SmartRefreshLayout对下拉刷新功能进行系统的拆分、组合,主要由四个部分组成:</p>    <ul>     <li> <p>RefreshLayout下拉的基本功能,包括布局测量、滑动事件处理、参数设定等等</p> </li>     <li> <p>RefreshContent对不同内容的统一封装,包括判断是否可滚动、回弹判断、智能识别</p> </li>     <li> <p>RefreshHeader下拉头部的实现和显示</p> </li>     <li> <p>RefreshFooter上拉底部的实现和显示</p> </li>    </ul>    <p>下面是UML关系类图</p>    <p><img src="https://simg.open-open.com/show/c85a9523bbf2160864b38497e4e1905b.jpg"></p>    <p>通过SmartRefreshLayout框架,你可以在一个稳定强大的下拉布局中实现自己项目需求的 Header ,不用去关心滑动事件处理,不用关心子控件的回弹和滚动边界,只需关注自己真正的项目需求Header的样子和动画。</p>    <h3>特点</h3>    <p>这时你会问:网上其他的开源下拉控件一样的可以自定义 Header 和 Footer ,SmartRefreshLayout 和它们比起来有什么优势?</p>    <p>变换方式</p>    <ul>     <li> <p>Translate 平行移动特点: 最常见,HeaderView高度不会改变,</p> </li>     <li> <p>Scale 拉伸形变特点:在下拉和上弹(HeaderView高度改变)时候,会自动触发OnDraw事件</p> </li>     <li> <p>FixedFront 固定在前面特点:不会上下移动,HeaderView高度不会改变</p> </li>     <li> <p>FixedBehind 固定在后面特点:不会上下移动,HeaderView高度不会改变(类似微信浏览器效果)</p> </li>     <li> <p>Screen 全屏幕特点:固定在前面,尺寸充满整个布局</p> </li>    </ul>    <p>SmartRefreshLayout 的Header和Footer都有多种变换方式,适应不同风格的 Header 和 Footer,下面是不同变换方式Header的Demo</p>    <p>FixedBehind 固定在后面和 <strong>Scale 拉伸形变</strong></p>    <p><img src="https://simg.open-open.com/show/6c49eea710eb2b76d0147005fea08ca7.gif" alt="Android开源:SmartRefreshLayout-智能下拉刷新框架" width="300" height="533"> <img src="https://simg.open-open.com/show/995781eb516f6ade533a3fc68f04cb9e.gif" alt="Android开源:SmartRefreshLayout-智能下拉刷新框架" width="300" height="533"></p>    <p>Screen 全屏幕和 <strong>Translate 平行移动</strong></p>    <p><img src="https://simg.open-open.com/show/9e1c057f0144a98c52e3959cacc11391.gif" alt="Android开源:SmartRefreshLayout-智能下拉刷新框架" width="300" height="533"> <img src="https://simg.open-open.com/show/6439e5532941f3bdc0fc1441ee0f2cc6.gif" alt="Android开源:SmartRefreshLayout-智能下拉刷新框架" width="300" height="533"></p>    <p>整理来自:<a href="/misc/goto?guid=4958864078206473805">Ultra-Pull-To-Refresh</a>,<a href="/misc/goto?guid=4958961145379939077">WaterDrop</a></p>    <p>  看到这么多炫酷的Header,是不是觉得很棒?这时你或许会担心这么多的Header集成在一起,但是平时只会用到一个,是不是要引入很多无用的代码和资源?</p>    <p>  请放心,我已经把刷新布局分成三个包啦,用到的时候自行引用就可以啦!</p>    <ul>     <li>SmartRefreshLayout 刷新布局核心实现,自带ClassicsHeader(经典)、BezierRadarHeader(贝塞尔雷达)两个 Header.</li>     <li>SmartRefreshHeader 各种Header的集成,除了Layout自带的Header,其他都在这个包中.</li>     <li>SmartRefreshFooter 各种Footer的集成,除了Layout自带的Footer,其他都在这个包中.</li>    </ul>    <h2>简单用例</h2>    <p>1.在 buld.gradle 中添加依赖</p>    <pre>  <code class="language-java">compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.1'  compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.1'//如果使用了特殊的Header  </code></pre>    <p>2.在XML布局文件中添加 SmartRefreshLayout</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"      android:id="@+id/refreshLayout"      android:layout_width="match_parent"      android:layout_height="match_parent">      <android.support.v7.widget.RecyclerView          android:id="@+id/recyclerview"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:overScrollMode="never"          android:background="#fff" />  </com.scwang.smartrefresh.layout.SmartRefreshLayout></code></pre>    <p>3.在 Activity 或者 Fragment 中添加代码</p>    <pre>  <code class="language-java">RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout);  refreshLayout.setOnRefreshListener(new OnRefreshListener() {      @Override      public void onRefresh(RefreshLayout refreshlayout) {          refreshlayout.finishRefresh(2000);      }  });  refreshLayout.setOnLoadmoreListener(new OnLoadmoreListener() {      @Override      public void onLoadmore(SmartRefreshLayout refreshlayout) {          refreshlayout.finishLoadmore(2000);      }  });</code></pre>    <h2>使用指定的 Header 和 Footer</h2>    <p>1.方法一 全局设置</p>    <pre>  <code class="language-java">//设置全局的Header构建器  SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() {          @Override          public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {              return new ClassicsHeader(context);//指定为经典Header,默认是 贝塞尔雷达Header          }      });  //设置全局的Footer构建器  SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() {          @Override          public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {              return new ClassicsFooter(context);//指定为经典Footer,默认是 BallPulseFooter          }      });</code></pre>    <p>注意:方法一 设置的Header和Footer的优先级是最低的,如果同时还使用了方法二、三,将会被其他方法取代</p>    <p>2.方法二 XML布局文件指定</p>    <pre>  <code class="language-java">    <com.scwang.smartrefresh.layout.SmartRefreshLayout          xmlns:app="http://schemas.android.com/apk/res-auto"          android:id="@+id/smartLayout"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:background="#444444"          app:srlPrimaryColor="#444444"          app:srlAccentColor="@android:color/white"          app:srlEnablePreviewInEditMode="true">          <!--srlAccentColor srlPrimaryColor 将会改变 Header 和 Footer 的主题颜色-->          <!--srlEnablePreviewInEditMode 可以开启和关闭预览功能-->          <com.scwang.smartrefresh.layout.header.ClassicsHeader              android:layout_width="match_parent"              android:layout_height="wrap_content"              app:srlClassicsSpinnerStyle="FixedBehind"/>          <!--FixedBehind可以让Header固定在内容的背后,下拉的时候效果同微信浏览器的效果-->          <TextView              android:layout_width="match_parent"              android:layout_height="match_parent"              android:padding="@dimen/padding_common"              android:background="@android:color/white"              android:text="@string/description_define_in_xml"/>          <com.scwang.smartrefresh.layout.footer.ClassicsFooter              android:layout_width="match_parent"              android:layout_height="wrap_content"              app:srlClassicsSpinnerStyle="FixedBehind"/>          <!--FixedBehind可以让Footer固定在内容的背后,下拉的时候效果同微信浏览器的效果-->      </com.scwang.smartrefresh.layout.SmartRefreshLayout></code></pre>    <p>注意:方法二 XML设置的Header和Footer的优先级是中等的,会被方法三覆盖。而且使用本方法的时候,Android Studio 会有预览效果,如下图:</p>    <p><a href="/misc/goto?guid=4959750352060789347"><img alt="" src="https://simg.open-open.com/show/fa25348dc923988e49b23b5f2136d8a5.jpg"></a></p>    <p>不过不用担心,只是预览效果,运行的时候只有下拉才会出现~</p>    <p>3.方法三 Java代码设置</p>    <pre>  <code class="language-java">final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.smartLayout);  //设置 Header 为 Material风格  refreshLayout.setRefreshHeader(new MaterialHeader(this).setShowBezierWave(true));  //设置 Footer 为 球脉冲  refreshLayout.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale));  </code></pre>    <h2>属性 Attributes</h2>    <table>     <thead>      <tr>       <th>名称-name</th>       <th>格式-format</th>       <th>描述-description</th>      </tr>     </thead>     <tbody>      <tr>       <td>srlPrimaryColor</td>       <td>color</td>       <td>主题颜色</td>      </tr>      <tr>       <td>srlAccentColor</td>       <td>color</td>       <td>强调颜色</td>      </tr>      <tr>       <td>srlReboundDuration</td>       <td>integer</td>       <td>释放后回弹动画时长</td>      </tr>      <tr>       <td>srlHeaderHeight</td>       <td>dimension</td>       <td>Header的标准高度</td>      </tr>      <tr>       <td>srlFooterHeight</td>       <td>dimension</td>       <td>Footer的标准高度</td>      </tr>      <tr>       <td>srlDragRate</td>       <td>float</td>       <td>显示拖动高度/真实拖动高度(默认0.5,阻尼效果)</td>      </tr>      <tr>       <td>srlHeaderMaxDragRate</td>       <td>float</td>       <td>Header最大拖动高度/Header标准高度(默认2,要求>=1)</td>      </tr>      <tr>       <td>srlFooterMaxDragRate</td>       <td>float</td>       <td>Footer最大拖动高度/Footer标准高度(默认2,要求>=1)</td>      </tr>      <tr>       <td>srlEnableRefresh</td>       <td>boolean</td>       <td>是否开启下拉刷新功能(默认true)</td>      </tr>      <tr>       <td>srlEnableLoadmore</td>       <td>boolean</td>       <td>是否开启加上拉加载功能(默认true)</td>      </tr>      <tr>       <td>srlEnableHeaderTranslationContent</td>       <td>boolean</td>       <td>拖动Header的时候是否同时拖动内容(默认true)</td>      </tr>      <tr>       <td>srlEnableFooterTranslationContent</td>       <td>boolean</td>       <td>拖动Footer的时候是否同时拖动内容(默认true)</td>      </tr>      <tr>       <td>srlEnablePreviewInEditMode</td>       <td>boolean</td>       <td>是否在编辑模式时显示预览效果(默认true)</td>      </tr>      <tr>       <td>srlDisableContentWhenRefresh</td>       <td>boolean</td>       <td>是否在刷新的时候禁止内容的一切手势操作(默认false)</td>      </tr>      <tr>       <td>srlDisableContentWhenLoading</td>       <td>boolean</td>       <td>是否在加载的时候禁止内容的一切手势操作(默认false)</td>      </tr>     </tbody>    </table>    <h2>方法 Method</h2>    <table>     <thead>      <tr>       <th>名称-name</th>       <th>格式-format</th>       <th>描述-description</th>      </tr>     </thead>     <tbody>      <tr>       <td>setPrimaryColors</td>       <td>colors</td>       <td>主题\强调颜色</td>      </tr>      <tr>       <td>setPrimaryColorsId</td>       <td>colors</td>       <td>主题\强调颜色资源Id</td>      </tr>      <tr>       <td>setReboundDuration</td>       <td>integer</td>       <td>释放后回弹动画时长</td>      </tr>      <tr>       <td>setHeaderHeight</td>       <td>dimension</td>       <td>Header的标准高度(px/dp 两个版本)</td>      </tr>      <tr>       <td>setFooterHeight</td>       <td>dimension</td>       <td>Footer的标准高度(px/dp 两个版本)</td>      </tr>      <tr>       <td>setDragRate</td>       <td>float</td>       <td>显示拖动高度/真实拖动高度(默认0.5,阻尼效果)</td>      </tr>      <tr>       <td>setHeaderMaxDragRate</td>       <td>float</td>       <td>Header最大拖动高度/Header标准高度(默认2,要求>=1)</td>      </tr>      <tr>       <td>setFooterMaxDragRate</td>       <td>float</td>       <td>Footer最大拖动高度/Footer标准高度(默认2,要求>=1)</td>      </tr>      <tr>       <td>setEnableRefresh</td>       <td>boolean</td>       <td>是否开启下拉刷新功能(默认true)</td>      </tr>      <tr>       <td>setEnableLoadmore</td>       <td>boolean</td>       <td>是否开启加上拉加载功能(默认true)</td>      </tr>      <tr>       <td>setEnableHeaderTranslationContent</td>       <td>boolean</td>       <td>拖动Header的时候是否同时拖动内容(默认true)</td>      </tr>      <tr>       <td>setEnableFooterTranslationContent</td>       <td>boolean</td>       <td>拖动Footer的时候是否同时拖动内容(默认true)</td>      </tr>      <tr>       <td>setEnableAutoLoadmore</td>       <td>boolean</td>       <td>是否监听列表滚动到底部时触发加载事件</td>      </tr>      <tr>       <td>setDisableContentWhenRefresh</td>       <td>boolean</td>       <td>是否在刷新的时候禁止内容的一切手势操作(默认false)</td>      </tr>      <tr>       <td>setDisableContentWhenLoading</td>       <td>boolean</td>       <td>是否在加载的时候禁止内容的一切手势操作(默认false)</td>      </tr>      <tr>       <td>setReboundInterpolator</td>       <td>Interpolator</td>       <td>设置回弹动画的插值器</td>      </tr>      <tr>       <td>setRefreshHeader</td>       <td>RefreshHeader</td>       <td>设置指定的Header</td>      </tr>      <tr>       <td>setRefreshFooter</td>       <td>RefreshFooter</td>       <td>设置指定的Footer</td>      </tr>      <tr>       <td>setOnRefreshListener</td>       <td>OnRefreshListener</td>       <td>设置刷新监听器</td>      </tr>      <tr>       <td>setOnLoadmoreListener</td>       <td>OnLoadmoreListener</td>       <td>设置加载监听器</td>      </tr>      <tr>       <td>setOnRefreshLoadmoreListener</td>       <td>OnRefreshLoadmoreListener</td>       <td>同时设置上面两个监听器</td>      </tr>      <tr>       <td>setOnMultiPurposeListener</td>       <td>OnMultiPurposeListener</td>       <td>设置多功能监听器</td>      </tr>      <tr>       <td>setLoadmoreFinished</td>       <td>boolean</td>       <td>设置全部数据加载完成,之后不会触发加载事件</td>      </tr>      <tr>       <td>finishRefresh</td>       <td>(int delayed)</td>       <td>完成刷新,结束刷新动画</td>      </tr>      <tr>       <td>finishLoadmore</td>       <td>(int delayed)</td>       <td>完成加载,结束加载动画</td>      </tr>      <tr>       <td>getRefreshHeader</td>       <td>RefreshHeader</td>       <td>获取Header</td>      </tr>      <tr>       <td>getRefreshFooter</td>       <td>RefreshFooter</td>       <td>获取Footer</td>      </tr>      <tr>       <td>getState</td>       <td>RefreshState</td>       <td>获取当前状态</td>      </tr>      <tr>       <td>isRefreshing</td>       <td>boolean</td>       <td>是否正在刷新</td>      </tr>      <tr>       <td>isLoading</td>       <td>boolean</td>       <td>是否正在加载</td>      </tr>      <tr>       <td>autoRefresh</td>       <td>(int delayed)</td>       <td>触发自动刷新</td>      </tr>      <tr>       <td>autoLoadmore</td>       <td>(int delayed)</td>       <td>触发自动加载</td>      </tr>     </tbody>    </table>    <p>项目主页:<a href="http://www.open-open.com/lib/view/home/1499311685720">http://www.open-open.com/lib/view/home/1499311685720</a></p>