RecyclerView是android5.0之后出现的列表控件,可以在android-support-v7包中找到,是ListView的升级版本,更加先进和灵活。而SwipeRefreshLayout则是Google自己推出的下拉刷新控件,下面就来通过利用SwipeRefreshLayout + RecyclerView实现一个具有上拉加载和下拉刷新功能的自定义组件。
public class MyRefreshLayout extends FrameLayout {
private Context mContext;
private int mCurrentPage;// 当前页
private int mStartPage = 0;// 默认开始页数
private int mPageSize = 10;// 每页数量
private int lastVisibleItemPosition;
private boolean isCanLoadMore;
private boolean isLoading;
private LinearLayoutManager mLayoutManager;
private Adapter mAdapter;
private RecyclerView mRecyclerView;
private SwipeRefreshLayout mSwipeRefreshLayout;
private OnRefreshLayoutListener mListener;
public void setListener(OnRefreshLayoutListener listener) {
this.mListener = listener;
}
public interface OnRefreshLayoutListener {
// 刷新当前页面
void onRefresh();
// 加载更多数据
void onLoadMore();
}
public MyRefreshLayout(Context context) {
this(context, null);
}
public MyRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initViews(context);
}
private void initViews(Context context) {
mContext = context;
mCurrentPage = mStartPage;
isCanLoadMore = true;
isLoading = true;
View view = LayoutInflater.from(context).inflate(R.layout.refresh_layout, null);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout);
mSwipeRefreshLayout.setColorSchemeResources(
android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
// 第一次显示加载
mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
});
mSwipeRefreshLayout.setOnRefreshListener(new MyRefreshListener());
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.addOnScrollListener(new MyScrollListener());
this.addView(view);
}
public void setAdapter(Adapter adapter) {
if (adapter != null) {
mAdapter = adapter;
mRecyclerView.setAdapter(adapter);
}
}
public void setItemAnimator(ItemAnimator animator) {
if (animator != null) {
mRecyclerView.setItemAnimator(animator);
}
}
public int getCurrentPage() {
return mCurrentPage;
}
public void setStartPage(int page) {
this.mStartPage = page;
mCurrentPage = mStartPage;
}
public void setPageSize(int mPageSize) {
this.mPageSize = mPageSize;
}
public void setLinearLayout() {
mLayoutManager = new LinearLayoutManager(mContext);
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
}
// 刷新数据完成
public void refreshCompleted(boolean isSuccess) {
if (isSuccess) {
mCurrentPage = mStartPage;
mAdapter.notifyDataSetChanged();
}
mSwipeRefreshLayout.setRefreshing(false);
isLoading = false;
}
// 加载数据完成
public void loadingCompleted(boolean isSuccess) {
if (isSuccess) {
mCurrentPage++;
mAdapter.notifyDataSetChanged();
}
mSwipeRefreshLayout.setRefreshing(false);
isLoading = false;
}
// 是否可以下拉刷新
public void setPullRefreshEnable(boolean enable) {
mSwipeRefreshLayout.setEnabled(enable);
}
// 是否可以加载更多
public void setLoadMoreEnable(boolean enable) {
isCanLoadMore = enable;
}
private class MyScrollListener extends OnScrollListener {
public MyScrollListener() {
super();
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (isCanLoadMore && !isLoading && newState == RecyclerView.SCROLL_STATE_IDLE
&& mAdapter.getItemCount() >= mPageSize && lastVisibleItemPosition + 1 == mAdapter.getItemCount()) {
isLoading = true;
mSwipeRefreshLayout.setRefreshing(true);
if (mListener != null) {
mListener.onLoadMore();
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (isCanLoadMore && !isLoading) {
lastVisibleItemPosition = mLayoutManager.findLastVisibleItemPosition();
}
}
}
private class MyRefreshListener implements SwipeRefreshLayout.OnRefreshListener {
@Override
public void onRefresh() {
if (!isLoading) {
isLoading = true;
if (mListener != null) {
mListener.onRefresh();
}
}
}
}
}
实现上拉刷新的功能,利用SwipeRefreshLayout.OnRefreshListener接口就行了,而实现下拉加载功能,则通过RecyclerView.OnScrollListener接口中的onScrollStateChanged和onScrolled方法,在onScrolled方法中获取到列表当前最底下item可见的位置,然后在onScrollStateChanged方法中判断是否已经到达底部,从而加载数据。