下拉刷新框架-SmartRefreshLayout

本文将用以下几类做介绍:

  1. git地址
  2. 示例
  3. 常用方法
//布局文件引入控件
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);



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值