Android实战----RecyclerView下拉刷新和上拉加载的简单实现
Posted Herman-Hong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android实战----RecyclerView下拉刷新和上拉加载的简单实现相关的知识,希望对你有一定的参考价值。
一、简介
关于RecyclerView的介绍网上有很多文章,这里不做过多说明,也不与ListView相比较。本文旨在基于RecyclerView实现下拉刷新和上拉加载,简单的不能再简单了。
二、代码托管
https://github.com/honghailiang/RecyclerView_RefreshAndLoadMore
三、实现思路
1)下拉刷新
可以基于android控件SwipeRefreshLayout实现
2)上拉加载更多
可以基于RecyclerView的addOnScrollListener实现,具体实现下面一一详解
四、下拉刷新
布局中只需包一层SwipeRefreshLayout即可:activity_main.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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/pageBack"
tools:context="com.hhl.jtt.recyclerview_refreshandloadmore.MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_test_list"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_test_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
设置监听器:MainActivity.Java
private void initListener()
//下拉刷新
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
@Override
public void onRefresh()
new Handler().postDelayed(new Runnable()
@Override
public void run()
initData();
mAdapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
, 1000);
);
监听到下拉时就重新填充数据
五、上拉加载更多
布局上需要,两个item布局,一个正常显示数据,另外一个显示“上拉加载更多”
1)显示数据布局item_test.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:background="@color/white"
android:layout_marginBottom="1dp">
<TextView
android:text=""
android:layout_width="wrap_content"
android:layout_height="40dp"
android:id="@+id/tv_test_id"
android:layout_gravity="center"
android:textColor="@color/black" />
</LinearLayout>
2)显示上拉加载更多布局item_swipe_footer.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp">
<ProgressBar
android:id="@+id/pb_swipe_wait"
android:layout_width="20dp"
android:layout_height="20dp" />
<TextView
android:text="@string/load_more"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:id="@+id/loading_status"
android:layout_toRightOf="@+id/pb_swipe_wait"
android:layout_toEndOf="@+id/pb_swipe_wait"
android:gravity="center_vertical"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"/>
</RelativeLayout>
重要的是在适配器中
3)适配器使用 MainActivity.Java
private void initView()
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new TestListAdapter(this, this, recyclerView, testList);
recyclerView.setAdapter(mAdapter);
4)适配器工作 TestListAdapter.Java
package com.hhl.jtt.recyclerview_refreshandloadmore;
import android.content.Context;
import android.os.Handler;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by DELL on 2017/3/14.
* 适配器
*/
public class TestListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
private LayoutInflater layoutInflater;
private static final int VIEW_ITEM = 0; //普通Item View
private static final int TYPE_FOOTER = 1; //底部FootView
private static final int TYPE_FINISH = -1; //完成FootView
private List list;
private int lastVisibleItemPosition; //最后各一个项目位置
private MyViewHolder mvHolder;
private MyProgressViewHolder mpHolder;
private RecyclerView.LayoutParams param;
private ILoadMoreData iLoadMoreData;
private int totalNum = 20;//测试总条数,利用该值判断是否加载更多,可以通过外部设置该值
public TestListAdapter(Context context, final ILoadMoreData iLoadMoreData,
RecyclerView recyclerView, List list)
this.layoutInflater = LayoutInflater.from(context);
this.list = list;
this.iLoadMoreData = iLoadMoreData;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
super.onScrollStateChanged(recyclerView, newState);
//判断是否到底部了
if (newState ==RecyclerView.SCROLL_STATE_IDLE &&
lastVisibleItemPosition + 1 == getItemCount())
new Handler().postDelayed(new Runnable()
@Override
public void run()
//如果还有数据则加载更多
if(!getIsFinish())
iLoadMoreData.loadMoreData();
,1000);
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView,dx, dy);
//获取最后一个项目位置
lastVisibleItemPosition =linearLayoutManager.findLastVisibleItemPosition();
);
private boolean getIsFinish()
return list.size() == totalNum;
/**
* 由于包含加载更多项,因此需要加1
* @return
*/
@Override
public int getItemCount()
return list == null ? 0 : list.size()+1;
//根据position判断显示item的类型
@Override
public int getItemViewType(int position)
if(position + 1 != getItemCount())
return VIEW_ITEM;
else
if(getItemCount()-1 ==totalNum)
return TYPE_FINISH;
else
return TYPE_FOOTER;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
if (viewType == VIEW_ITEM)
View view = layoutInflater.inflate(R.layout.item_test, parent, false);
mvHolder = new MyViewHolder(view);
return mvHolder;
else if (viewType == TYPE_FOOTER)
View view = layoutInflater.inflate(R.layout.item_swipe_footer, parent, false);
mpHolder = new MyProgressViewHolder(view);
return mpHolder;
else
//全部数据加载完,不在显示加载更多
View view = layoutInflater.inflate(R.layout.item_swipe_footer, parent, false);
mpHolder = new MyProgressViewHolder(view);
param = (RecyclerView.LayoutParams) view.getLayoutParams();
view.setVisibility(View.GONE);
param.height = 0;
param.width = 0;
view.setLayoutParams(param);
return mpHolder;
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
if (position + 1 != getItemCount())
MyViewHolder myViewHolder = (MyViewHolder) holder;
myViewHolder.tvTestId.setText((CharSequence) list.get(position));
myViewHolder.tvTestId.setTag(position);
myViewHolder.tvTestId.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
iLoadMoreData.myOnClick(v);
);
/**
* 显示内容Holder
*/
class MyViewHolder extends RecyclerView.ViewHolder
@BindView(R.id.tv_test_id)
TextView tvTestId;
public MyViewHolder(View view)
super(view);
ButterKnife.bind(this, view);
/**
* 显示加载更多Holder
*/
class MyProgressViewHolder extends RecyclerView.ViewHolder
public MyProgressViewHolder(View view)
super(view);
可以看出实现原理非常简单,根据设置总数与list中数目比较,是否显示加载更多item
/**
* 由于包含加载更多项,因此需要加1
* @return
*/
@Override
public int getItemCount()
return list == null ? 0 : list.size()+1;
//根据position判断显示item的类型
@Override
public int getItemViewType(int position)
if(position + 1 != getItemCount())
return VIEW_ITEM;
else
if(getItemCount()-1 ==totalNum)
return TYPE_FINISH;
else
return TYPE_FOOTER;
RecyclerView设置滑动监听器,只在底部显示加载更多时及有更多数据需要加载时才进行加载操作
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
super.onScrollStateChanged(recyclerView, newState);
//判断是否到底部了,是否是加载更多item
if (newState ==RecyclerView.SCROLL_STATE_IDLE &&
lastVisibleItemPosition + 1 == getItemCount())
new Handler().postDelayed(new Runnable()
@Override
public void run()
//如果还有数据则加载更多
if(!getIsFinish())
iLoadMoreData.loadMoreData();
,1000);
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView,dx, dy);
//获取最后一个项目位置
lastVisibleItemPosition =linearLayoutManager.findLastVisibleItemPosition();
);
判断是否有更多数据加载
private boolean getIsFinish()
return list.size() == totalNum;
六、效果
1)下拉刷新
2)上拉加载更多
以上是关于Android实战----RecyclerView下拉刷新和上拉加载的简单实现的主要内容,如果未能解决你的问题,请参考以下文章
Android实战----RecyclerView下拉刷新和上拉加载的简单实现