.
前面写了一个自定义的RecyclerView适配器,实现RecyclerView的下拉刷新有两种方式.
1、重写RecyclerView.Adapter的 getItemViewType(int position)方法,根据不同位置返回不同类型即可。可以利用这个特性把第0个位置预留出来,固定把第0个item存放下拉刷新的view
2、在RecyclerView外部嵌套一个类似SwipeRefreshLayout的控件,然后给SwipeRefreshLayout添加刷新监听函数,在刷新监听函数中我们重新获取数据,并更新RecyclerView的数据,这里推荐一个智能下拉刷新框架SmartRefreshLayout
SmartRefreshLayout的目标是打造一个强大,稳定,成熟的下拉刷新框架,并集成各种的炫酷、多样、实用、美观的Header和Footer。 正如名字所说,SmartRefreshLayout是一个“聪明”或者“智能”的下拉刷新布局,由于它的“智能”,它不只是支持所有的View,还支持多层嵌套的视图结构。 它继承自ViewGroup 而不是FrameLayout或LinearLayout,提高了性能。 也吸取了现在流行的各种刷新布局的优点,包括谷歌官方的 SwipeRefreshLayout, 其他第三方的 Ultra-Pull-To-Refresh、TwinklingRefreshLayout 。 还集成了各种炫酷的 Header 和 Footer。
地址:https://github.com/scwang90/SmartRefreshLayout
第一种方式这里先不介绍,如有疑问可以看陈宇明大佬的万能适配器源码
V7包版本
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-28'
implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0-alpha-28'//没有使用特殊Header,可以不加这行
implementation 'com.android.support:appcompat-v7:25.3.1'//版本 23以上(必须)
androidx 版本
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-andx-11'
implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0-andx-11'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
2.1布局
2.2布局设置Header和Footer
SmartRefreshLayout中如果有多个控件,第一个控件会变成Header,第二个控件作为主体,第三个控件则是Footer
在SmartRefreshLayout中,LinearLayout将作为主体,ClassicsHeader和ClassicsFooter分别为Header和Footer
2.3代码设置Header和Footer
代码设置会覆盖布局设置的Header和Footer
//修改阻尼效果(0 - 1),越小阻尼越大,默认0.5
refreshLayout.setDragRate(0.6f);
//设置主题颜色
refreshLayout.setPrimaryColorsId(R.color.colorPrimary)
//设置 Header 为 贝塞尔雷达 样式
refreshLayout.setRefreshHeader(BezierRadarHeader(this).setEnableHorizontalDrag(true))
//设置 Footer 为 球脉冲 样式
refreshLayout.setRefreshFooter(BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale))
自带Header
//设置 Header 为 气球快递 样式
refreshLayout.setRefreshHeader(DeliveryHeader(this))
//设置 Header 为 掉落盒子 样式
refreshLayout.setRefreshHeader(DropBoxHeader(this))
//官方 样式
refreshLayout.setRefreshHeader(MaterialHeader(this))
//苹果水滴 样式
refreshLayout.setRefreshHeader(WaterDropHeader(this))
//经典样式
refreshLayout.setRefreshHeader(ClassicsHeader(this))
//弹出文字 样式
refreshLayout.setRefreshHeader(StoreHouseHeader(this))
//弹出圆圈 样式
refreshLayout.setRefreshHeader(BezierCircleHeader(this))
//贝塞尔雷达 样式 ,setEnableHorizontalDrag设置启用水平拖动
refreshLayout.setRefreshHeader(BezierRadarHeader(this))
//弹出水滴 样式 ,水滴需要一半屏幕高度,慎用
refreshLayout.setRefreshHeader(WaveSwipeHeader(this))
//淘宝二楼 样式
refreshLayout.setRefreshHeader(TwoLevelHeader(this))
//坦克游戏 样式
refreshLayout.setRefreshHeader(FunGameBattleCityHeader(this))
//打砖块游戏 样式
refreshLayout.setRefreshHeader(FunGameHitBlockHeader(this))
//金色校园 样式
refreshLayout.setRefreshHeader(PhoenixHeader(this))
//冲上云霄 样式
refreshLayout.setRefreshHeader(TaurusHeader(this))
自带Footer
//球脉冲 样式
//setSpinnerStyle设置变形样式,Scale为拉伸,Translate平行移动
//FixedBehind固定在背后,FixedFront固定在前面,MatchLayout填满布局
refreshLayout.setRefreshFooter(BallPulseFooter(this)
.setSpinnerStyle(SpinnerStyle.FixedBehind))
//经典Footer 样式
refreshLayout.setRefreshFooter(ClassicsFooter(this)
.setSpinnerStyle(SpinnerStyle.Scale))
2.4下拉刷新
//是否启用下拉刷新(默认启用)
refreshLayout.setEnableRefresh(true);
//下拉监听
refreshLayout.setOnRefreshListener {
//重置所有item
mAdapter.replaceData(newList)
if (isRefresh){
load = 0;
it.finishRefresh()
}else{
it.finishRefresh(false)
}
}
在下拉监听中可以关闭加载更多功能
refreshLayout.setOnRefreshListener {
if (isRefresh){
//load等于3,表示没有更多数据了
if(load == 3){
//完成刷新并标记没有更多数据,不再触发加载更多事件
it.finishRefreshWithNoMoreData()
}
}else{
it.finishRefresh(false)
}
}
在下拉监听中可以使用以下方法恢复加载更多功能
it.finishRefresh()
//恢复加载更多事件
it.resetNoMoreData()
2.5加载更多
//设置是否启用上拉加载更多(默认启用)
refreshLayout.setEnableLoadMore(true);
//内容不满一页时不能开启上拉加载功能
refreshLayout.setEnableLoadMoreWhenContentNotFull(false);
//上拉监听
refreshLayout.setOnLoadMoreListener {
//加载数据
mAdapter.addNewItem(Person("加载更多","$load"))
//isLoad为true加载成功,否则加载失败
if (isLoad){
//load等于3,表示没有更多数据了
if(load == 3){
//显示全部加载完成,并不再触发加载更多事件
it.finishLoadMoreWithNoMoreData()
}else{
load++
//完成加载更多
it.finishLoadMore()
}
}else{
it.finishLoadMore(false);
}
}
3.1回弹动画时长
refreshLayout.setReboundDuration(300);
3.2关闭越界回弹、越界拖动、自动加载更多
代码方式
refreshLayout.setEnableAutoLoadMore(false);//使上拉加载具有弹性效果
refreshLayout.setEnableOverScrollDrag(false);//禁止越界拖动(1.0.4以上版本)
refreshLayout.setEnableOverScrollBounce(false);//关闭越界回弹功能
xml方式
app:srlEnableOverScrollDrag="false"
app:srlEnableAutoLoadMore="false"
app:srlEnableOverScrollBounce="false"
3.3关闭自动加载更多
代码方式
refreshlayout.setEnableAutoLoadMore(false);
xml方式
app:srlEnableAutoLoadMore="false"
3.4获取当前状态
refreshLayout.getState() == RefreshState.None //空闲状态
refreshLayout.getState() == RefreshState.Loading//代替 isLoading
refreshLayout.getState() == RefreshState.Refreshing//代替 isRefreshing
refreshLayout.getState().isOpening // 等同于 isLoading || isRefreshing
refreshLayout.getState().isDragging //判断是否正在拖拽刷新控件(非拖拽列表)
refreshLayout.getState().isFinishing //判断动画是否正在结束
refreshLayout.getState().isHeader //判断当前是否处于 Header 的一系列状态中
refreshLayout.getState().isFooter //判断当前是否处于 Footer 的一系列状态中
3.5修改经典刷新文字
在Application 中修改
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
//"下拉可以刷新";
ClassicsHeader.REFRESH_HEADER_PULLING = getString(R.string.header_pulling);
//"正在刷新...";
ClassicsHeader.REFRESH_HEADER_REFRESHING = getString(R.string.header_refreshing);
//"正在加载...";
ClassicsHeader.REFRESH_HEADER_LOADING = getString(R.string.header_loading);
//"释放立即刷新";
ClassicsHeader.REFRESH_HEADER_RELEASE = getString(R.string.header_release);
//"刷新完成";
ClassicsHeader.REFRESH_HEADER_FINISH = getString(R.string.header_finish);
//"刷新失败";
ClassicsHeader.REFRESH_HEADER_FAILED = getString(R.string.header_failed);
//"上次更新 M-d HH:mm";
ClassicsHeader.REFRESH_HEADER_UPDATE = getString(R.string.header_update);
//"'Last update' M-d HH:mm";
ClassicsHeader.REFRESH_HEADER_UPDATE = getString(R.string.header_update);
//"释放进入二楼"
ClassicsHeader.REFRESH_HEADER_SECONDARY = getString(R.string.header_secondary);
//"上拉加载更多";
ClassicsFooter.REFRESH_FOOTER_PULLING = getString(R.string.footer_pulling);
//"释放立即加载";
ClassicsFooter.REFRESH_FOOTER_RELEASE = getString(R.string.footer_release);
//"正在刷新...";
ClassicsFooter.REFRESH_FOOTER_LOADING = getString(R.string.footer_loading);
//"正在加载...";
ClassicsFooter.REFRESH_FOOTER_REFRESHING = getString(R.string.footer_refreshing);
//"加载完成";
ClassicsFooter.REFRESH_FOOTER_FINISH = getString(R.string.footer_finish);
//"加载失败";
ClassicsFooter.REFRESH_FOOTER_FAILED = getString(R.string.footer_failed);
//"全部加载完成";
ClassicsFooter.REFRESH_FOOTER_NOTHING = getString(R.string.footer_nothing);
}
}
XML直接指定
3.6触发下拉刷新的距离
SmartRefresh触发下拉刷新的距离就是 Header 的高度乘以比率:HeaderHeight*HeaderTriggerRate,下拉的距离超过这个值释放时就可以触发刷新事件,否则回弹到原始状态。
HeaderTriggerRate 默认是 1,改成0.5,那么再下拉到一半的时候就可以刷新了 改变这个距离就是 setHeaderHeight,footer 类推
相关方法
setHeaderHeight //Header的标准高度
setFooterHeight //Footer的标准高度
setHeaderTriggerRate//Header触发刷新距离与HeaderHeight的比率(默认1)
setFooterTriggerRate//Footer触发加载距离与FooterHeight的比率(默认1)
相关属性
srlHeaderHeight //Header的标准高度(dp)
srlFooterHeight //Footer的标准高度(dp)
srlHeaderTriggerRate //Header触发刷新距离与HeaderHeight的比率(默认1)
srlFooterTriggerRate //Footer触发加载距离与FooterHeight的比率(默认1)
//设置 Header 起始位置偏移量 1.0.5
refreshLayout.setFooterHeaderInsetStart(0);
//设置 Footer 起始位置偏移量 1.0.5
refreshLayout.setFooterFooterInsetStart(0);
//最大显示下拉高度/Header标准高度
refreshLayout.setHeaderMaxDragRate(2);
//最大显示下拉高度/Footer标准高度
refreshLayout.setFooterMaxDragRate(2);
3.7阻尼效果参数
相关方法
setDragRate //设置拖动比率
setHeaderMaxDragRate//Header最大拖动距离与HeaderHeight的比率(默认2.5)
setFooterMaxDragRate //Footer最大拖动距离与FooterHeight的比率(默认2.5)
相关属性
srlDragRate //设置拖动比率
srlHeaderMaxDragRate//Header最大拖动距离与HeaderHeight的比率(默认2.5)
srlFooterMaxDragRate //Footer最大拖动距离与FooterHeight的比率(默认2.5)
3.8嵌套滚动
//是否启用嵌套滚动
refreshLayout.setEnableNestedScroll(false);
3.9其他
//是否在加载完成时滚动列表显示新的内容
refreshLayout.setEnableScrollContentWhenLoaded(true);.
//是否下拉Header的时候向下平移列表或者内容
refreshLayout.setEnableHeaderTranslationContent(true);
//是否上拉Footer的时候向上平移列表或者内容
refreshLayout.setEnableFooterTranslationContent(true);
//是否在刷新完成时滚动列表显示新的内容 1.0.5
refreshLayout.setEnableScrollContentWhenRefreshed(true);
//是否剪裁Header当时样式为FixedBehind时1.0.5
refreshLayout.srlEnableClipHeaderWhenFixedBehind(true);
//是否剪裁Footer当时样式为FixedBehind时1.0.5
refreshLayout.srlEnableClipFooterWhenFixedBehind(true);
//是否在刷新的时候禁止列表的操作
refreshLayout.setDisableContentWhenRefresh(false);
//是否在加载的时候禁止列表的操作
refreshLayout.setDisableContentWhenLoading(false);
//设置多功能监听器
refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener());
//设置滚动边界判断
refreshLayout.setScrollBoundaryDecider(new ScrollBoundaryDecider());
//自定义滚动边界
refreshLayout.setScrollBoundaryDecider(new ScrollBoundaryDeciderAdapter());
//自动刷新
refreshLayout.autoRefresh();
//自动加载
refreshLayout.autoLoadMore();
//自动刷新,只显示动画不执行刷新
refreshLayout.autoRefreshAnimationOnly();
//自动加载,只显示动画不执行加载
refreshLayout.autoLoadMoreAnimationOnly();
//延迟400毫秒后自动刷新
refreshLayout.autoRefresh(400);
//延迟400毫秒后自动加载
refreshLayout.autoLoadMore(400);
//关闭正在打开状态的 Header 或者 Footer(1.1.0)
refreshLayout.closeHeaderOrFooter();
//恢复没有更多数据的原始状态 1.0.5
refreshLayout.setNoMoreData(false);