框架?下拉刷新控件还能框架化?智能又怎么回事?二话很少少先上Demo效果图,我们再来探个究竟。html
Github 传送门 注意:本文仅仅是博客文章,主要用于项目介绍和宣传,因为发布时间关系,部份内容已通过期,详细使用文档请跳转 githubjava
Demo
下载 APK-Demoandroid
若是手机上看不到图片,能够尝试git
项目演示
风格演示
##框架 若是你看完了效果图,或许框架的意思应该有所了解了~~SmartRefreshLayout对下拉刷新功能进行系统的拆分、组合,主要由四个部分组成:github
- RefreshLayout 下拉的基本功能,包括布局测量、滑动事件处理、参数设定等等
- RefreshContent 对不一样内容的统一封装,包括判断是否可滚动、回弹判断、智能识别
- RefreshHeader 下拉头部的实现和显示
- RefreshFooter 上拉底部的实现和显示
下面是UML关系类图segmentfault
经过SmartRefreshLayout框架,你能够在一个稳定强大的下拉布局中实现本身项目需求的 Header ,不用去关心滑动事件处理,不用关心子控件的回弹和滚动边界,只需关注本身真正的项目需求Header的样子和动画。浏览器
###特色 这时你会问:网上其余的开源下拉控件同样的能够自定义 Header 和 Footer ,SmartRefreshLayout 和它们比起来有什么优点?微信
####变换方式app
- Translate 平行移动 特色: 最多见,HeaderView高度不会改变,
- Scale 拉伸形变 特色:在下拉和上弹(HeaderView高度改变)时候,会自动触发OnDraw事件
- FixedFront 固定在前面 特色:不会上下移动,HeaderView高度不会改变
- FixedBehind 固定在后面 特色:不会上下移动,HeaderView高度不会改变(相似微信浏览器效果)
- Screen 全屏幕 特色:固定在前面,尺寸充满整个布局
SmartRefreshLayout 的Header和Footer都有多种变换方式,适应不一样风格的 Header 和 Footer,下面是不一样变换方式Header的Demo框架
FixedBehind 固定在后面 和 Scale 拉伸形变
Screen 全屏幕 和 Translate 平行移动
####独立事件 Header和Footer 能够独立的处理手指滑动事件来为动画提供操做指令,也可使用RefreshLayout的核心接口来完成一些不寻常的操做指令。 下面的打砖块 Header中 ,Header能够独立的使用滑动事件来为游戏挡板提供指令,并同时能够调用核心接口来通知RefreshLayout上下滚动列表
智能
智能是什么玩意?有什么用?智能主要体现 SmartRefreshLayout 对未知布局的自动识别上,这样可让咱们更高效的实现咱们所需的功能,也能够实现一些非寻常的功能。下面经过自定义Header 和 嵌套Layout做为内容 来解释 SmartRefreshLayout 的智能之处。
###自定义Header 咱们来看这一下这个伪代码例子:
<SmartRefreshLayout> <ClassicsHeader/> <TextView/> <ClassicsFooter/> </SmartRefreshLayout>
在Android Studio 中的预览效果图
对比代码和咱们预想的同样,那咱们来对代码作一些改动,ClassicsHeader换成一个简单的TextView,看看会发生什么?
<SmartRefreshLayout> <TextView android:layout_width="match_parent" android:layout_height="100dp" android:gravity="center" android:background="#444" android:textColor="#fff" android:text="看看我会不会变成Header"/> <TextView/> <ClassicsFooter/> </SmartRefreshLayout>
在Android Studio 中的预览效果图 和 运行效果图
这时发现咱们咱们替换的 TextView 自动就变成了Header,只是它还不会动。要动起来?那么太简单啦,网上随便一搜索就一大堆的 gif 。如这里:拖拖拖 ~~垃机C4D,相似的咱们还能够找到不少,又如:环游东京30天:GIF版旅行指南
那咱们就选择 环游东京30天:GIF版旅行指南 中的这张:
接着咱们来改代码:
compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.3'//一个开源gif控件
<SmartRefreshLayout> <pl.droidsonroids.gif.GifImageView android:layout_width="match_parent" android:layout_height="150dp" android:scaleType="centerCrop" android:src="@mipmap/gif_header_repast"/> <ListView/> <ClassicsFooter/> </SmartRefreshLayout>
在 Android Studio 中的预览效果图 和 运行效果图
哈哈!一行Java代码都不用写,就完成了一个自定义的Header
###嵌套Layout做为内容
若是boos要求在列表的前面固定一个广告条怎么办?这好办呀,通常咱们会开开心心的下下这样的代码:
<LinearLayout android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="100dp" android:gravity="center" android:text="我就是boos要求加上的广告条啦"/> <SmartRefreshLayout> <ListView/> </SmartRefreshLayout> </LinearLayout>
可是在运行下拉刷新的时候,咱们发现 Header是在广告条之下的,看着会别扭~,其实咱们能够试试另外一种方式,把广告条写到 RefreshLayout内部,看看会发生什么?
<SmartRefreshLayout> <LinearLayout android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="100dp" android:gravity="center" android:text="我就是boos要求加上的广告条啦"/> <ListView/> </LinearLayout> </SmartRefreshLayout>
因为伪代码过于简单,并且运行效果过于丑陋,这里仍是贴出在实际项目中的实际状况吧~
咱们注意看右边的图,仔细观察手指触摸的位置和下拉效果。能够看到在列表已经滚动到中部时,轻微下拉列表是不会触发刷新的,可是若是是触摸固定的布局,则能够触发下拉。从这里能够看出 SmartRefreshLayout 对滚动边界的判断是动态的,智能的!固然若是 SmartRefreshLayout 的智能仍是不能知足你,能够经过 setListener 本身实现滚动边界的判断,更为准确!
##功能
简单的介绍了两大特色框架和智能,接下来也说说SmartRefreshLayout还具备的其余经常使用功能吧~
- 支持全部的 View(AbsListView、RecyclerView、WebView....View) 和多层嵌套的 Layout
- 支持自定义而且已经集成了不少炫酷的 Header 和 Footer
- 支持和ListView的同步滚动 和 RecyclerView、AppBarLayout、CoordinatorLayout 的嵌套滚动 NestedScrolling.
- 支持在Android Studio Xml 编辑器中预览 效果
- 支持分别在 Default(默认)、Xml、JavaCode 等三个地方设置 Header 和 Footer.
- 支持自动刷新、自动上拉加载(自动检测列表滚动到底部,而不用手动上拉).
- 支持通用的刷新监听器 OnRefreshListener 和更详细的滚动监听 OnMultiPurposeListener.
- 支持自定义回弹动画的插值器,实现各类炫酷的动画效果.
- 支持设置主题来适配任何场景的App,不会出现炫酷但很尴尬的状况.
- 支持设置多种滑动方式来适配各类效果的Header和Footer:位置平移、尺寸拉伸、背后固定、顶层固定、全屏
- 支持内容尺寸自适应 Content-wrap_content
- 支持继承重写和扩展功能,内部实现没有 private 方法和字段,继承以后均可以重写覆盖
- 支持越界回弹(Listview、RecyclerView、ScrollView、WebView...View)
##使用
###简单用例
1.在 buld.gradle 中添加依赖
compile 'com.android.support:appcompat-v7:25.3.1'//版本随意 compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.4' compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.4'//没有使用特殊Header,能够不加这行
2.在XML布局文件中添加 SmartRefreshLayout
<?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>
3.在 Activity 或者 Fragment 中添加代码
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(RefreshLayout refreshlayout) { refreshlayout.finishLoadmore(2000); } });
使用指定的 Header 和 Footer
1.方法一 全局设置
public class App extends Application { static {//static 代码段能够防止内存泄露 //设置全局的Header构建器 SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() { @Override public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色 return new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.Translate);//指定为经典Header,默认是 贝塞尔雷达Header } }); //设置全局的Footer构建器 SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() { @Override public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { //指定为经典Footer,默认是 BallPulseFooter return new ClassicsFooter(context).setSpinnerStyle(SpinnerStyle.Translate); } }); } }
注意:方法一 设置的Header和Footer的优先级是最低的,若是同时还使用了方法2、三,将会被其余方法取代
2.方法二 XML布局文件指定
<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"/> <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"/> </com.scwang.smartrefresh.layout.SmartRefreshLayout>
注意:方法二 XML设置的Header和Footer的优先级是中等的,会被方法三覆盖。并且使用本方法的时候,Android Studio 会有预览效果,以下图:
不过不用担忧,只是预览效果,运行的时候只有下拉才会出现~
3.方法三 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));