最近用RecyclerView和SwipeRefreshLayout实现了一个下拉刷新和上拉加载更多的功能,在这里给大家分享一下。
一般下拉刷新和上拉加载更多是对服务器端发送请求,服务器端首先要写一个分页读取数据库的方法。例如getList(int pageNo).(下面就一直使用这个方法,来作为服务器端的方法)
1、xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="lzl.com.recyclerviewdemo.MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/list_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
2、初始化数据
private void initView() {
//设置刷新条
initSwipeRefresh();
recyclerView = (RecyclerView) findViewById(R.id.list_recycler);
mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setHasFixedSize(true);
//初始化,一直显示第一条数据。
getList(1);
//在设置adapter之前要先获取list集合。
recyclerView.setAdapter(adapter);
footView = LayoutInflater.from(this).inflate(R.layout.recycler_foot,recyclerView,false);
adapter.setFootView(footView);
setRecyclerScrollListener();
}
/**
* 初始化下拉刷新条。
*/
private void initSwipeRefresh(){
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh);
//设置刷新条的颜色
swipeRefreshLayout.setColorSchemeColors(
R.color.colorAccent,R.color.colorPrimary,R.color.colorPrimaryDark);
swipeRefreshLayout.setOnRefreshListener(this);
//第一次进入页面时,显示加载进度条
swipeRefreshLayout.setProgressViewOffset(false,0,(int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources()
.getDisplayMetrics()));
swipeReFreshState(true); //开始进入界面,显示刷新条
}
以上是将SwipeRefreshLayout设置一些布局,
//设置刷新条的颜色
swipeRefreshLayout.setColorSchemeColors(
R.color.colorAccent,R.color.colorPrimary,R.color.colorPrimaryDark);
swipeRefreshLayout.setOnRefreshListener(this);
//第一次进入页面时,显示加载进度条
swipeRefreshLayout.setProgressViewOffset(false,0,(int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources()
.getDisplayMetrics()));
swipeReFreshState(true); //开始进入界面,显示刷新条
}
private void swipeReFreshState(boolean b) {
swipeRefreshLayout.setRefreshing(b);
}
并且创建RecyclerView对象。
3、下拉刷新
主要是实现SwipeRefreshLayout的onRefresh()方法。然后执行获取数据的方法。下拉刷新一直是刷新最新的数据。
@Override
public void onRefresh() {
//先清空list集合中的数据
list.clear();
//刷新第一页数据
getList(1);
}
/**
* 这里模拟分页,出入的是页数
* 然后根据每页显示的个数进行更新数据。
* @param pageNo
*/
public void getList(int pageNo){
pageNum = pageNo;
int pageCount = 6; //每页显示6条数据。
for(int i=(pageNo-1)*pageCount;i<pageCount * pageNo;i++){
if(i == totalPage){
return;
}
list.add("显示第"+(i+1)+"条数据");
}
pageNum++;
adapter.notifyDataSetChanged();
//数据更新以后,刷新条消失
swipeReFreshState(false);
}
4、上拉加载更多
调用RecyclerView的setOnScrollListener()方法,监听上拉加载事件的发生。
if(lastItem+1 == adapter.getItemCount() && newState == RecyclerView.SCROLL_STATE_IDLE)
具体的代码实现
private void setRecyclerScrollListener() {
recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if(lastItem+1 == adapter.getItemCount() && newState == RecyclerView.SCROLL_STATE_IDLE){
//最后一个item并且还有下滑的趋势
if(lastItem+1 <= totalPage){
getList(pageNum);
//显示底部加载信息
adapter.footVisible();
}else{
TextView loadMoreTv = (TextView) footView.findViewById(R.id.loadMore_tv);
ProgressBar loadMorePb = (ProgressBar) footView.findViewById(R.id.loadMore_pb);
loadMorePb.setVisibility(View.GONE);
loadMoreTv.setText("没有更多数据");
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
lastItem = mLayoutManager.findLastVisibleItemPosition();
}
});
}
5、Adapter布局的实现
因为设置有FootView的显示内容,所以List数据应该比实际的List数据多一。下面是具体的实现
public class MainAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<String> list;
private Context cxt;
private final int TYPE_item = 1;
private final int TYPE_FOOT = 2;
private View footView;
private int realListSize;
public MainAdapter(Context context,List<String> list){
this.cxt = context;
this.list = list;
}
public void setFootView(View foot){
this.footView = foot;
footGone();
}
public void footGone(){
if(footView == null){
return;
}
footView.setVisibility(View.GONE);
}
public void footVisible(){
if(footView == null){
return;
}
footView.setVisibility(View.VISIBLE);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_FOOT && footView !=null){
//当viewType是TYPE_FOOT并且footView不为空的时候,就可以显示FootView了。
return new FootViewHolder(footView);
}
View view = LayoutInflater.from(cxt).inflate(R.layout.recyclerview_item,parent,false);
return new DataViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof DataViewHolder){
//设置动态信息
((DataViewHolder) holder).infoTv.setText(list.get(position));
}
}
@Override
public int getItemViewType(int position) {
//如果是最后一条数据,就返回FootView类型
if(position+1 == getItemCount()){
return TYPE_FOOT;
}
return TYPE_item;
}
@Override
public int getItemCount() {
if(list==null){
return 0;
}
//如果footView为空的话,就是获取list.size()个数据。
realListSize = (footView == null ? list.size() : list.size()+1);
return realListSize;
}
class DataViewHolder extends RecyclerView.ViewHolder {
TextView infoTv;
public DataViewHolder(View itemView) {
super(itemView);
infoTv = (TextView) itemView.findViewById(R.id.info_tv);
}
}
class FootViewHolder extends RecyclerView.ViewHolder {
public FootViewHolder(View itemView) {
super(itemView);
}
}
}