天天看点

基于ViewGroup和RecyclerView的自定义下拉刷新上拉加载列表--SwipeUpdateLayout的使用SwipeUpdateLayout简介SwipeUpdateLayout接入SwipeUpdateLayout使用总结

SwipeUpdateLayout开发文档

  • SwipeUpdateLayout简介
  • SwipeUpdateLayout接入
  • SwipeUpdateLayout使用
    • 下拉刷新
      • 使用默认头部视图样式
      • 修改默认头部视图样式
      • 自定义头部视图
    • 上拉加载更多
      • 使用默认底部视图样式
      • 修改默认底部视图样式
      • 自定义底部视图
    • 空数据/错误信息视图
      • 使用默认空数据/错误信息视图样式
      • 修改默认空数据/错误信息视图样式
      • 自定义空数据/错误信息视图
    • 加载视图
      • 使用默认加载视图样式
      • 修改默认加载视图样式
      • 自定义加载视图
  • 总结

SwipeUpdateLayout简介

SwipeUpdateLayout是一个支持下拉刷新、上拉加载更多、空数据/错误信息视图展示、点击重新加载的纵向列表。

实际上是一个ViewGroup+RecyclerView的自定义控件,目前仅支持使用RecyclerView作为列表视图,后续会考虑适配ListView、ScrollView和WebView等等。

先上默认的效果图

基于ViewGroup和RecyclerView的自定义下拉刷新上拉加载列表--SwipeUpdateLayout的使用SwipeUpdateLayout简介SwipeUpdateLayout接入SwipeUpdateLayout使用总结

SwipeUpdateLayout接入

在根目录的build.gradle添加Maven依赖:

allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}
           

在module目录的build.gradle添加以下依赖:

dependencies {
	        implementation 'com.github.LiZhuoFan:SwipeUpdateLayout:1.1.1'
	}
           

右上角Sync Now走起,再喝上一口可乐…OK,没有报错,接入成功。

SwipeUpdateLayout使用

用法跟正常控件一样,在布局文件上加上SwipeUpdateLayout然后再findViewById就可以了。但是SwipeUpdateLayout默认情况是不支持简介中的所有功能的,除非在布局文件上加上了SwipeUpdateLayout定义的属性。就是说,如果什么属性都没加上,SwipeUpdateLayout与一个普通的纵向RecyclerView无异。所以如果你不需要相关的功能就直接用RecyclerView好了,用SwipeUpdateLayout只会多一层嵌套。

目前支持如下自定义属性,请留意注释:

<declare-styleable name="SwipeUpdateLayout">
        <!--必须是继承com.droven.swipeupdatelayout.base.BaseLoadingView的详细类名-->
        <attr name="loadingView" format="string" />
        <!--加载图标-->
        <attr name="loadingIcon" format="reference" />
        <!--加载文字-->
        <attr name="loadingText" format="string" />
        <!--必须是继承com.droven.swipeupdatelayout.base.BaseEmptyView的详细类名-->
        <attr name="emptyView" format="string" />
        <!--空数据图标-->
        <attr name="emptyIcon" format="reference" />
        <!--空数据文字-->
        <attr name="emptyText" format="string" />
        <!--错误图标-->
        <attr name="failIcon" format="reference" />
        <!--错误文字-->
        <attr name="failText" format="string" />
        <!--必须是继承com.droven.swipeupdatelayout.base.BaseRefreshView的详细类名-->
        <attr name="headerView" format="string" />
        <!--头部图标-->
        <attr name="headerIcon" format="reference" />
        <!--头部正常状态文字-->
        <attr name="headerNormalText" format="string" />
        <!--头部可刷新时文字-->
        <attr name="headerCanRefreshText" format="string" />
        <!--头部正在刷新时文字-->
        <attr name="headerRefreshingText" format="string" />
        <!--头部刷新完成时文字-->
        <attr name="headerCompleteText" format="string" />
        <!--必须是继承com.droven.swipeupdatelayout.base.BaseRefreshView的详细类名-->
        <attr name="footerView" format="string" />
        <!--尾部图标-->
        <attr name="footerIcon" format="reference" />
        <!--尾部正常状态文字-->
        <attr name="footerNormalText" format="string" />
        <!--尾部可加载时文字-->
        <attr name="footerCanLoadText" format="string" />
        <!--尾部正在加载时文字-->
        <attr name="footerLoadingText" format="string" />
        <!--尾部加载完成时文字-->
        <attr name="footerCompleteText" format="string" />
    </declare-styleable>
           

xxxView:可以使用自己定义的View,但是必须按照注释上说的继承某个base类

xxxIcon/xxxText:在默认样式的基础上修改相应内容

注意

1、没有添加属性就没有对应的功能,例如,如果loadingView、loadingIcon和loadingText都没添加的话SwipeUpdateLayout就不支持加载视图的功能;

2、当使用xxxView之后,xxxIcon和xxxText都会无效;

3、xxxIcon和xxxText只要添加了其中一个就会使用默认样式并修改对应内容。

SwipeUpdateLayout内嵌套了RecyclerView,故无需在布局文件上添加RecyclerView

//可以直接setAdapter给到嵌套的RecyclerView
    swipeUpdateLayout.setAdapter(adapter);
    
    //可以获取到嵌套的RecyclerView,然后可以调用RecyclerView的相关方法
    swipeUpdateLayout.getDataView();
           

下拉刷新

添加headerXxx相关属性,再加上下拉刷新的监听就能使用下拉刷新功能,如果没有加上监听是不会有下拉刷新功能的。

swipeUpdateLayout.setOnRefreshListener(new SwipeUpdateLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            
        }
    });

    //数据获取之后调用以下方法关闭头部视图
    swipeUpdateLayout.loadComplete();

    //动态开启和关闭下拉刷新功能
    swipeUpdateLayout.setRefreshEnable(enable);
           

使用默认头部视图样式

使用默认头部视图只需要添加如下属性

app:headerView="SwipeUpdateHeaderView"
           

修改默认头部视图样式

<!--删之-->
    app:headerView="SwipeUpdateHeaderView"

    <!--加之,具体解释看上面的属性列表-->
    app:headerIcon=""<!--loading效果是仿支付宝蚂蚁森林的loading效果-->
    app:headerNormalText=""
    app:headerCanRefreshText=""
    app:headerRefreshingText=""
    app:headerCompleteText=""
           

自定义头部视图

创建一个继承com.droven.swipeupdatelayout.base.BaseRefreshView的类并实现其中的抽象方法,如:

package com.droven.swipeupdatelayout.demo;

import android.view.View;
import com.droven.swipeupdatelayout.base.BaseRefreshView;

public class MyHeaderView extends BaseRefreshView {
    /**
     * layout的ID
     */
    @Override
    protected int layoutResId() {
        return 0;
    }
    /**
     * 初始化view
     */
    @Override
    protected void initView(View view) {
    }
    /**
     * 可刷新、加载更多的高度
     * 用于拖拽时切换文字内容
     */
    @Override
    public int canRefreshHeight() {
        return 0;
    }
    /**
     * 拖拽中但未达到可刷新的高度
     */
    @Override
    public void onNormal() {
    }
    /**
     * 拖拽中且已达到可刷新的高度
     */
    @Override
    public void onCanRefresh() {
    }
    /**
     * 释放后,刷新中
     */
    @Override
    public void onRefreshing() {
    }
    /**
     * 刷新完成
     */
    @Override
    public void onComplete() {
    }
    /**
     * 拖拽过程的回调,可用于边拖拽边慢慢切换图片状态(动画)
     *
     * @param top 拖拽高度
     */
    @Override
    public void onDragging(int top) {
    }
}
           
具体实现可以参考com.droven.swipeupdatelayout.view.SwipeUpdateHeaderView

然后在布局文件上添加属性:

<!--必须是完整的类名,否则无法实例化-->
    app:headerView="com.droven.swipeupdatelayout.demo.MyHeaderView"
           

上拉加载更多

添加footerXxx相关属性,再加上上拉加载的监听就能使用上拉加载功能,如果没有加上监听是不会有上拉加载功能的。

swipeUpdateLayout.setOnLoadMoreListener(new SwipeUpdateLayout.OnLoadMoreListener() {
        @Override
        public void onLoadMore() {
            
        }
    });

    //数据获取之后调用以下方法关闭头部视图
    swipeUpdateLayout.loadComplete();

    //动态开启和关闭上拉加载更多功能
    swipeUpdateLayout.setLoadMoreEnable(enable);
           

使用默认底部视图样式

使用默认底部视图只需要添加如下属性

app:footerView="SwipeUpdateFooterView"
           

修改默认底部视图样式

<!--删之-->
    app:footerView="SwipeUpdateFooterView"

    <!--加之,具体解释看上面的属性列表-->
    app:footerIcon=""<!--laoding效果为360度旋转-->
    app:footerNormalText=""
    app:footerCanLoadText=""
    app:footerLoadingText=""
    app:footerCompleteText=""
           

自定义底部视图

创建一个继承com.droven.swipeupdatelayout.base.BaseRefreshView的类并实现其中的抽象方法,与头部视图同理,不在此复述了。然后在布局文件上添加属性:

<!--必须是完整的类名,否则无法实例化-->
    app:footerView="com.droven.swipeupdatelayout.demo.MyFooterView"
           
具体实现可以参考com.droven.swipeupdatelayout.view.SwipeUpdateFooterView

空数据/错误信息视图

添加emptyXxx或failXxx相关属性,当RecyclerView没有数据的时候会自动出现空数据视图,当网络错误或其他问题出错的时候调用如下方法就会出现错误信息视图:

swipeUpdateLayout.loadFail("网错错误");
    swipeUpdateLayout.loadFail();//当设置了app:failText=""之后才有效
           
空数据视图和错误信息视图为同一个View,只不过是不同情况展示不同内容

添加监听实现点击视图重新加载的回调

swipeUpdateLayout.setOnReloadListener(new SwipeUpdateLayout.OnReloadListener() {
        @Override
        public void onReload() {
            
        }
    });
           

使用默认空数据/错误信息视图样式

使用默认底部视图只需要添加如下属性

app:emptyView="SwipeUpdateEmptyView"
           

修改默认空数据/错误信息视图样式

<!--删之-->
    app:emptyView="SwipeUpdateEmptyView"

    <!--加之,具体解释看上面的属性列表-->
    app:emptyIcon=""
    app:emptyText=""
    app:failIcon=""
    app:failText=""<!--调用swipeUpdateLayout.loadFail()才有效-->
           

自定义空数据/错误信息视图

创建一个继承com.droven.swipeupdatelayout.base.BaseEmptyView的类并实现其中的抽象方法,如:

package com.droven.swipeupdatelayout.demo;

import android.view.View;
import com.droven.swipeupdatelayout.base.BaseEmptyView;

public class MyEmptyView extends BaseEmptyView {
    /**
     * layout的ID
     */
    @Override
    protected int layoutResId() {
        return 0;
    }
    /**
     * 初始化view
     */
    @Override
    protected void initView(View view) {

    }
    /**
     * 点击重新加载的ViewId,返回null或空数组则不实现点击重新加载
     */
    @Override
    public View[] clickToReloadView() {
        return new View[0];
    }
    /**
     * 没数据时
     */
    @Override
    public void onEmpty() {

    }
    /**
     * 加载出错时
     */
    @Override
    public void onFail(String errMsg) {

    }
}
           
具体实现可以参考com.droven.swipeupdatelayout.view.SwipeUpdateEmptyView

然后在布局文件上添加属性:

<!--必须是完整的类名,否则无法实例化-->
    app:emptyView="com.droven.swipeupdatelayout.demo.MyEmptyView"
           

加载视图

添加loadingXxx相关属性,在RecyclerView第一等待加载数据和点击空数据/错误信息视图重新加载的时候,都会自动展示加载动画,当数据加载完或空数据或调用了加载出错的方法之后会自动消失,无需调用方法处理。

使用默认加载视图样式

使用默认底部视图只需要添加如下属性

app:loadingView="SwipeUpdateLoadingView"
           

修改默认加载视图样式

<!--删之-->
    app:loadingView="SwipeUpdateLoadingView"

    <!--加之,具体解释看上面的属性列表-->
    app:loadingIcon=""<!--laoding效果为360度旋转-->
    app:loadingText=""
           

自定义加载视图

创建一个继承com.droven.swipeupdatelayout.base.BaseLoadingView的类并实现其中的抽象方法,如:

package com.droven.swipeupdatelayout.demo;

import android.view.View;
import com.droven.swipeupdatelayout.base.BaseLoadingView;

public class MyLoadingView extends BaseLoadingView {
    /**
     * layout的ID
     */
    @Override
    protected int layoutResId() {
        return 0;
    }
    /**
     * 初始化view
     */
    @Override
    protected void initView(View view) {

    }
    /**
     * 首次加载/重新加载中
     */
    @Override
    public void onLoading() {

    }
    /**
     * 首次加载/重新加载完成
     */
    @Override
    public void onLoadFinished() {

    }
}
           
具体实现可以参考com.droven.swipeupdatelayout.view.SwipeUpdateLoadingView

然后在布局文件上添加属性:

<!--必须是完整的类名,否则无法实例化-->
    app:laodingView="com.droven.swipeupdatelayout.demo.MyLoadingView"
           

总结

SwipeUpdateLayout提供了以上所述的功能且能够灵活地自定义视图,但是目前只能作用于RecyclerView上,后期会考虑做适配和优化。

源码和demo已经上传到Gayhub,有兴趣的可以看看和提issue

https://github.com/LiZhuoFan/SwipeUpdateLayout