业务需要RecyclerView增加上拉刷新,下拉加载更多功能,于是写了个Demo,看看运行效果。
main.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="match_parent"
android:orientation="vertical">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiprefreshlayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
TestActivity:
package comm.example.hongentao.recyclerviewloadmore;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by hongentao on 16/3/10.
*/
public class TestActivity extends Activity {
private RecyclerView mRecyclerView;
private TestAdapter mTestAdapter;
private LinearLayoutManager mLayoutManager;
private Handler myHandler;
private SwipeRefreshLayout mSwipRefreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initView();
init();
}
private void initView() {
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mSwipRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiprefreshlayout);
}
private void init() {
myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mTestAdapter = new TestAdapter(this, mRecyclerView);
final List<String> mList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
mList.add("haha");
}
mTestAdapter.mList.clear();
mTestAdapter.mList.addAll(mList);
mTestAdapter.setLoadMore(true);
mTestAdapter.addOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void loadMore() {
mTestAdapter.mList.add(null);
mTestAdapter.notifyItemInserted(mTestAdapter.mList.size() - 1);
myHandler.postDelayed(new Runnable() {
@Override
public void run() {
mTestAdapter.mList.remove(mTestAdapter.mList.size() - 1);
mTestAdapter.notifyItemRemoved(mTestAdapter.mList.size());
for (int i = 0; i < 30; i++) {
mTestAdapter.mList.add("haha");
mTestAdapter.notifyItemInserted(mTestAdapter.mList.size());
}
mTestAdapter.setLoaded();
}
}, 2 * 1000);
}
});
mSwipRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mTestAdapter.mList.clear();
final List<String> mList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
mList.add("haha");
}
mTestAdapter.mList.addAll(mList);
mTestAdapter.notifyDataSetChanged();
myHandler.postDelayed(new Runnable() {
@Override
public void run() {
mSwipRefreshLayout.setRefreshing(false);
}
}, 2 * 1000);
}
});
mRecyclerView.setAdapter(mTestAdapter);
}
}
TestAdapter:
package comm.example.hongentao.recyclerviewloadmore;
import android.content.Context;
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.ProgressBar;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by hongentao on 16/3/10.
*/
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyHolder> {
private Context mContext;
private OnLoadMoreListener mOnLoadMoreListener;
public List<String> mList = new ArrayList<>();
public static final int LOADMORE = 1;
public static final int NORMAL = 2;
private int visibleItemCount;
private int totalItemCount;
private int firstVisibleItem;
private boolean loading = false;
private boolean isLoadMore = true;
public TestAdapter(Context context, RecyclerView recyclerView) {
this.mContext = context;
final LinearLayoutManager mLayoutManager;
if (recyclerView != null && recyclerView.getLayoutManager() instanceof
LinearLayoutManager) {
mLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// check for scroll down
if (isLoadMore) {
if (dy > 0) {
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (!loading) {
if (totalItemCount <= visibleItemCount + firstVisibleItem) {
if (mOnLoadMoreListener != null) {
mOnLoadMoreListener.loadMore();
}
loading = true;
}
}
}
}
}
});
}
}
/**
* 设置下拉加载更多功能
*
* @param isLoadMore
*/
public void setLoadMore(boolean isLoadMore) {
this.isLoadMore = isLoadMore;
}
/**
* reset loading status
*/
public void setLoaded() {
loading = false;
}
public void addOnLoadMoreListener(OnLoadMoreListener mLoadMoreListener) {
this.mOnLoadMoreListener = mLoadMoreListener;
}
@Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = null;
switch (viewType) {
case LOADMORE:
mView = LayoutInflater.from(mContext).inflate(R.layout.progressbar_item, null);
break;
case NORMAL:
mView = LayoutInflater.from(mContext).inflate(R.layout.list_item, null);
break;
}
return new MyHolder(mView, viewType);
}
@Override
public void onBindViewHolder(MyHolder holder, int position) {
if (mList.get(position) == null) {
holder.mProgressBar.setIndeterminate(true);
} else {
holder.mTextView.setText(mList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if (mList.get(position) == null) {
return LOADMORE;
} else {
return NORMAL;
}
}
@Override
public int getItemCount() {
return mList.size();
}
public class MyHolder extends RecyclerView.ViewHolder {
private TextView mTextView;
private ProgressBar mProgressBar;
public MyHolder(View itemView, int viewType) {
super(itemView);
init(itemView, viewType);
}
private void init(View view, int viewType) {
switch (viewType) {
case LOADMORE:
mProgressBar = (ProgressBar) view.findViewById(R.id.progressbar);
break;
case NORMAL:
mTextView = (TextView) view.findViewById(R.id.textview);
break;
default:
break;
}
}
}
}
下拉刷新采用v4自带的SwipRefreshLayout,上拉加载更多在RecyclerView的适配器中做文章, 通过viewType设置不同的item布局。巧妙的运用mList的源数据,如果mList.get(position) == null 就加载Loading布局, 反之就加载正常布局。 等到loading完成后,就remove掉loading布局。
recyclerView的onScrollListener监听是上拉加载更多的关键。
1:firstVisibleItem 当前可见的第一条数据item postion。
2:visibleItemCount当前可见屏幕上总的item条数。
3:totalItemCount总共的item count条数。
loadmore前提条件:
1:dy > 0
当RecyclerView Y轴上滑动距离大于0时才会触发,这样的话当RecyclerView item数较少无法充满RecyclerView时,触摸RecyclerView不会滚动,进而不会触发LoadMore功能。
2:(totalItemCount <= visibleItemCount + firstVisibleItem)
当前可见的item总数 + 可见范围内第一个item的位置 >= item的总数,表明item已经滑动到最后了。
onLoadMoreListener:
package comm.example.hongentao.recyclerviewloadmore;
/**
* Created by hongentao on 16/3/10.
*/
public interface OnLoadMoreListener {
void loadMore();
}
list_item.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="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="50dp"/>
</LinearLayout>
progressbar_item.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="match_parent"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
github下载地址:
感觉对你有帮助的话,跪求star!!!