本文将用以下几类做介绍:
//布局文件引入控件
com.scwang.smartrefresh.layout.SmartRefreshLayout
//初始化RefreshLayout
RefreshLayout srlRefreshHead = (RefreshLayout) bindId(R.id.srl_refresh_head);
srlRefreshHead.setReboundDuration(500);
//内容不满一页时是否开启上拉加载功能
srlRefreshHead.setEnableLoadMoreWhenContentNotFull(false);
srlRefreshHead.setOnRefreshListener(refreshlayout -> {
EventBusUtils.post(new EventMsg<>().setType(RecruitConfig.UPDATE_RECRUIT).setData(refreshlayout));
// refreshlayout.finishRefresh(true/*,false*/);//传入false表示刷新失败
});
srlRefreshHead.setOnLoadMoreListener(refreshlayout -> {
refreshlayout.finishLoadMore(2000/*,false*/);//传入false表示加载失败
});
//判断状态
if (mSrlRefreshHead.getState().isDragging) {
Log.d("onOffsetChanged", "正在拖拽刷新控件(非拖拽列表)");
}
if (mSrlRefreshHead.getState().isFinishing) {
Log.d("onOffsetChanged", "动画正在结束");
}
if (mSrlRefreshHead.getState().isHeader) {
Log.d("onOffsetChanged", "处于 Header 的一系列状态中");
onPauseBanner();
}
if (mSrlRefreshHead.getState().isOpening) {
Log.d("onOffsetChanged", "isLoading || isRefreshing");
}
if (mSrlRefreshHead.getState() == RefreshState.None) {
if (Math.abs(state) < appBarLayout.getTotalScrollRange()) {
onResumeBanner();
}
Log.d("onOffsetChanged", "没有进行操作了");
}
//属性值
//下面示例中的值等于默认值
RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout);
refreshLayout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);
refreshLayout.setDragRate(0.5f);//显示下拉高度/手指真实下拉高度=阻尼效果
refreshLayout.setReboundDuration(300);//回弹动画时长(毫秒)
refreshLayout.setHeaderHeight(100);//Header标准高度(显示下拉高度>=标准高度 触发刷新)
refreshLayout.setHeaderHeightPx(100);//同上-像素为单位 (V1.1.0删除)
refreshLayout.setFooterHeight(100);//Footer标准高度(显示上拉高度>=标准高度 触发加载)
refreshLayout.setFooterHeightPx(100);//同上-像素为单位 (V1.1.0删除)
refreshLayout.setFooterHeaderInsetStart(0);//设置 Header 起始位置偏移量 1.0.5
refreshLayout.setFooterHeaderInsetStartPx(0);//同上-像素为单位 1.0.5 (V1.1.0删除)
refreshLayout.setFooterFooterInsetStart(0);//设置 Footer 起始位置偏移量 1.0.5
refreshLayout.setFooterFooterInsetStartPx(0);//同上-像素为单位 1.0.5 (V1.1.0删除)
refreshLayout.setHeaderMaxDragRate(2);//最大显示下拉高度/Header标准高度
refreshLayout.setFooterMaxDragRate(2);//最大显示下拉高度/Footer标准高度
refreshLayout.setHeaderTriggerRate(1);//触发刷新距离 与 HeaderHeight 的比率1.0.4
refreshLayout.setFooterTriggerRate(1);//触发加载距离 与 FooterHeight 的比率1.0.4
refreshLayout.setEnableRefresh(true);//是否启用下拉刷新功能
refreshLayout.setEnableLoadMore(false);//是否启用上拉加载功能
refreshLayout.setEnableAutoLoadMore(true);//是否启用列表惯性滑动到底部时自动加载更多
refreshLayout.setEnablePureScrollMode(false);//是否启用纯滚动模式
refreshLayout.setEnableNestedScroll(false);//是否启用嵌套滚动
refreshLayout.setEnableOverScrollBounce(true);//是否启用越界回弹
refreshLayout.setEnableScrollContentWhenLoaded(true);//是否在加载完成时滚动列表显示新的内容
refreshLayout.setEnableHeaderTranslationContent(true);//是否下拉Header的时候向下平移列表或者内容
refreshLayout.setEnableFooterTranslationContent(true);//是否上拉Footer的时候向上平移列表或者内容
refreshLayout.setEnableLoadMoreWhenContentNotFull(true);//是否在列表不满一页时候开启上拉加载功能
refreshLayout.setEnableFooterFollowWhenLoadFinished(false);//是否在全部加载结束之后Footer跟随内容1.0.4
refreshLayout.setEnableOverScrollDrag(false);//是否启用越界拖动(仿苹果效果)1.0.4
refreshLayout.setEnableScrollContentWhenRefreshed(true);//是否在刷新完成时滚动列表显示新的内容 1.0.5
refreshLayout.srlEnableClipHeaderWhenFixedBehind(true);//是否剪裁Header当时样式为FixedBehind时1.0.5
refreshLayout.srlEnableClipFooterWhenFixedBehind(true);//是否剪裁Footer当时样式为FixedBehind时1.0.5
refreshLayout.setDisableContentWhenRefresh(false);//是否在刷新的时候禁止列表的操作
refreshLayout.setDisableContentWhenLoading(false);//是否在加载的时候禁止列表的操作
refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener());//设置多功能监听器
refreshLayout.setScrollBoundaryDecider(new ScrollBoundaryDecider());//设置滚动边界判断
refreshLayout.setScrollBoundaryDecider(new ScrollBoundaryDeciderAdapter());//自定义滚动边界
refreshLayout.setRefreshHeader(new ClassicsHeader(context));//设置Header
refreshLayout.setRefreshFooter(new ClassicsFooter(context));//设置Footer
refreshLayout.setRefreshContent(new View(context));//设置刷新Content(用于非xml布局代替addView)1.0.4
refreshLayout.autoRefresh();//自动刷新
refreshLayout.autoLoadMore();//自动加载
refreshLayout.autoRefreshAnimationOnly();//自动刷新,只显示动画不执行刷新
refreshLayout.autoLoadMoreAnimationOnly();//自动加载,只显示动画不执行加载
refreshLayout.autoRefresh(400);//延迟400毫秒后自动刷新
refreshLayout.autoLoadMore(400);//延迟400毫秒后自动加载
refreshLayout.finishRefresh();//结束刷新
refreshLayout.finishLoadMore();//结束加载
refreshLayout.finishRefresh(3000);//延迟3000毫秒后结束刷新
refreshLayout.finishLoadMore(3000);//延迟3000毫秒后结束加载
refreshLayout.finishRefresh(false);//结束刷新(刷新失败)
refreshLayout.finishLoadMore(false);//结束加载(加载失败)
refreshLayout.finishLoadMoreWithNoMoreData();//完成加载并标记没有更多数据 1.0.4
refreshLayout.closeHeaderOrFooter();//关闭正在打开状态的 Header 或者 Footer(1.1.0)
refreshLayout.resetNoMoreData();//恢复没有更多数据的原始状态 1.0.4(1.1.0删除)
refreshLayout.setNoMoreData(false);//恢复没有更多数据的原始状态 1.0.5
}
}
//全局一次性设置默认属性和默认Header
public class App extends Application {
static {//使用static代码段可以防止内存泄漏
//设置全局默认配置(优先级最低,会被其他设置覆盖)
SmartRefreshLayout.setDefaultRefreshInitializer(new DefaultRefreshInitializer() {
@Override
public void initialize(@NonNull Context context, @NonNull RefreshLayout layout) {
//开始设置全局的基本参数(可以被下面的DefaultRefreshHeaderCreator覆盖)
layout.setReboundDuration(1000);
layout.setReboundInterpolator(new DropBounceInterpolator());
layout.setFooterHeight(100);
layout.setDisableContentWhenLoading(false);
layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);
}
});
//全局设置默认的 Header
SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() {
@Override
public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
//开始设置全局的基本参数(这里设置的属性只跟下面的MaterialHeader绑定,其他Header不会生效,能覆盖DefaultRefreshInitializer的属性和Xml设置的属性)
layout.setEnableHeaderTranslationContent(false);
return new MaterialHeader(context).setColorSchemeResources(R.color.colorRed,R.color.colorGreen,R.color.colorBlue);
}
});
}
}
//xml属性
<!--srlAccentColor:强调颜色-->
<!--srlPrimaryColor:主题颜色-->
<!--srlEnablePreviewInEditMode:是否启用Android Studio编辑xml时预览效果-->
<!--srlFixedFooterViewId:指定一个View在内容列表滚动时固定-->
<!--srlFixedHeaderViewId:指定一个View在内容列表滚动时固定-->
<!--srlHeaderTranslationViewId:指定下拉Header时偏移的视图Id-->
<!--srlFooterTranslationViewId:指定上拉Footer时偏移的视图Id-->
自定义刷新头部:
public class AppRefreshHeader extends LinearLayout implements RefreshHeader {
private TextView mHeaderText;//标题文本
// private PathsView mArrowView;//下拉箭头
private ImageView mProgressView;//刷新动画视图
// private ProgressDrawable mProgressDrawable;//刷新动画
public AppRefreshHeader(Context context) {
super(context);
initView(context);
}
public AppRefreshHeader(Context context, AttributeSet attrs) {
super(context, attrs);
this.initView(context);
}
public AppRefreshHeader(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.initView(context);
}
private void initView(Context context) {
setGravity(Gravity.CENTER);
setOrientation(VERTICAL);
mHeaderText = new TextView(context);
// mProgressDrawable = new ProgressDrawable();
// mArrowView = new PathsView(context);
mProgressView = new ImageView(context);
ImageUtils.setImage(context, mProgressView, R.drawable.load_gif);
// mProgressView.setImageDrawable(mProgressDrawable);
// mArrowView.parserPaths("M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z");
addView(mProgressView, SmartUtil.dp2px(70), SmartUtil.dp2px(70));
// addView(mArrowView, SmartUtil.dp2px(20), SmartUtil.dp2px(20));
// addView(new View(context), SmartUtil.dp2px(20), SmartUtil.dp2px(20));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 0, 0, SmartUtil.dp2px(12));
addView(mHeaderText, layoutParams);
setMinimumHeight(SmartUtil.dp2px(70));
}
/**
* 获取真实视图(必须返回,不能为null)
*/
@NonNull
@Override
public View getView() {
return this;
}
/**
* 获取变换方式(必须指定一个:平移、拉伸、固定、全屏)
*/
@NonNull
@Override
public SpinnerStyle getSpinnerStyle() {
return SpinnerStyle.Translate;
}
/**
* 设置主题颜色 (如果自定义的Header没有注意颜色,本方法可以什么都不处理)
*
* @param colors 对应Xml中配置的 srlPrimaryColor srlAccentColor
*/
@Override
public void setPrimaryColors(int... colors) {
mRefreshKernel.requestDrawBackgroundFor(this, colors[0]);
}
protected RefreshKernel mRefreshKernel;
/**
* 尺寸定义初始化完成 (如果高度不改变(代码修改:setHeader),只调用一次, 在RefreshLayout#onMeasure中调用)
*
* @param kernel RefreshKernel 核心接口(用于完成高级Header功能)
* @param height HeaderHeight or FooterHeight
* @param maxDragHeight 最大拖动高度
*/
@Override
public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) {
mRefreshKernel = kernel;
}
/**
* 手指拖动下拉(会连续多次调用,用于实时控制动画关键帧)
*
* @param percent 下拉的百分比 值 = offset/headerHeight (0 - percent - (headerHeight+maxDragHeight) / headerHeight )
* @param offset 下拉的像素偏移量 0 - offset - (headerHeight+maxDragHeight)
* @param height Header的高度
* @param maxDragHeight 最大拖动高度
* @param isDragging 下拉或者释放
*/
@Override
public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {
}
/**
* 手指释放之后的调用
*
* @param refreshLayout refreshLayout
* @param height Header的高度
* @param maxDragHeight 最大拖动高度
*/
@Override
public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {
}
/**
* 开始动画(开始刷新或者开始加载动画)
*
* @param refreshLayout RefreshLayout
* @param height HeaderHeight or FooterHeight
* @param maxDragHeight 最大拖动高度
*/
@Override
public void onStartAnimator(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {
// mProgressDrawable.start();//开始动画
}
/**
* 动画结束
*
* @param refreshLayout RefreshLayout
* @param success 数据是否成功刷新或加载
* @return 完成动画所需时间 如果返回 Integer.MAX_VALUE 将取消本次完成事件,继续保持原有状态
*/
@Override
public int onFinish(@NonNull RefreshLayout refreshLayout, boolean success) {
// mProgressDrawable.stop();//停止动画
if (success) {
mHeaderText.setText("刷新完成");
} else {
mHeaderText.setText("刷新失败");
}
return 500;//延迟500毫秒之后再弹回
}
@Override
public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {
}
@Override
public boolean isSupportHorizontalDrag() {
return false;
}
@Override
public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) {
switch (newState) {
case None:
//6
Log.i("onStateChanged", "None");
case PullDownToRefresh:
mHeaderText.setText("下拉开始刷新");
//1、7
Log.i("onStateChanged", "PullDownToRefresh");
break;
case PullDownCanceled:
//取消刷新
Log.i("onStateChanged", "PullDownCanceled");
break;
case ReleaseToTwoLevel:
Log.i("onStateChanged", "ReleaseToTwoLevel");
break;
case RefreshReleased:
//3
mHeaderText.setText("正在刷新中");
Log.i("onStateChanged", "RefreshReleased");
break;
case Refreshing:
//4
Log.i("onStateChanged", "Refreshing");
break;
case RefreshFinish:
//5
Log.i("onStateChanged", "RefreshFinish");
break;
case ReleaseToRefresh:
//2
mHeaderText.setText("释放立即刷新");
Log.i("onStateChanged", "ReleaseToRefresh");
break;
}
}
}
暂时禁用上拉加载:
在xml里给SmartRefreshLayout控件设置
app:srlEnableLoadMore="false"
刷新加载的逻辑示例:
//分页请求
private int mPageNumber;
//是否刷新
private boolean isRefresh;
//加载条数限制
private int mLoadLimit;
//取消内容不满一页时开启上拉加载功能
mSrlRefreshHead.setEnableLoadMoreWhenContentNotFull(false);
mSrlRefreshHead.setOnRefreshListener(refreshlayout -> {
//上拉刷新
mPageNumber = 1;
isRefresh = true;
//设置开启加载更多
mSrlRefreshHead.setEnableLoadMore(true);
getAcademicCircleTheme(mPageType);
});
mSrlRefreshHead.setOnLoadMoreListener(refreshlayout -> {
//下拉加载
mPageNumber++;
isRefresh = false;
getAcademicCircleTheme(mPageType);
});
/**
* 接口请求出错
*
* @param message message
*/
private void onErrorRequest(EventMsg message) {
switch ((Pull) message.getRequest()) {
case ACADEMIC_CIRCLE_THEME:
//获取学圈主题,如果是加载更多,则还原加载的条数
if (!isRefresh) mPageNumber--;
break;
}
}
//请求成功
//获取学圈主题
List<Map<String, Object>> listMap = message.getData();
if (listMap.size() < mLoadLimit) {
//没有更多数据
mSrlRefreshHead.setEnableLoadMore(false);
}
RecyclerViewUtils.updateData(mMapList, listMap, mMyCircleAdapterRv, mPageNumber <= 1);