3 分钟解决 Recycleview 的上拉加载更多和下拉刷新功能

10,050 阅读3分钟
原文链接: www.jianshu.com

一.下拉刷新 话不多说,前段时间做项目的时候刚用到过,分享出来集思广益,欢迎指出不足。本文主要利用SwipeRefreshLayout嵌套Recycleview实现简单的下拉刷新功能。

1.XML文件:

                       <?xml version="1.0" encoding="utf-8"?>
                    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swiperefreshlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:scrollbars="vertical" />

    </android.support.v4.widget.SwipeRefreshLayout>

</LinearLayout>

2.代码:Activity的OnCreate方法里只要添加几行代码就可实现下拉刷新的效果

                 swiperefreshlayout.setOnRefreshListener(this);
                 swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
         //发送网络请求
            sendRequest();
         //停止刷新
            swiperefreshlayout.setRefreshing(false);
         //刷新RecycleView
            mRecycleViewAdapter.notifyDataSetChanged();
        }
    });

二.上拉加载更多 看过网上很多关于上拉加载更多的文章,最后总结测试了一下,就有了适合自己的简单的上拉加载更多。主要采用Recycleview设置一个FootViewHolder,并监听Recycleview的滑动状态来实现效果。直接贴代码吧(Copy不能运行,只能自己截取有用的部分加以利用,耐着性子看完,相信会有收获哦)

1.XML文件:

                    <?xml version="1.0" encoding="utf-8"?>
                   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swiperefreshlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:scrollbars="vertical" />

    </android.support.v4.widget.SwipeRefreshLayout>

2.代码(主要为网络请求到的数据Copy无效,其他各位看官随意蹂躏):

1.Activity:

            public class MyActivity extends AppCompatActivity {
private NoticeAdapter adapter;
private RecyclerView noticeRecyclerview;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initData();
}

private void initData() {
    //news为你第一次发送网络请求获取到的List集合,这里就不贴了
    adapter = new NoticeAdapter(this,news);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    noticeRecyclerview.setLayoutManager(linearLayoutManager);
    noticeRecyclerview.setAdapter(adapter);
    noticeRecyclerview.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
    noticeRecyclerview.addOnScrollListener(monScrollListener);
    adapter.notifyDataSetChanged();
}
       //本段可直接Copy,作用是监听Recycleview是否滑动到底部
private int mLastVisibleItemPosition;
private RecyclerView.OnScrollListener monScrollListener = new RecyclerView.OnScrollListener() {

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof LinearLayoutManager) {
            mLastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
        }
        if (adapter != null) {
            if (newState == RecyclerView.SCROLL_STATE_IDLE
                    && mLastVisibleItemPosition + 1 == adapter.getItemCount()) {
                //发送网络请求获取更多数据
                sendMoreRequest();
            }
        }
    }


};

private void sendMoreRequest() {
    //可直接查看下面onResponse方法,网络请求操作不必细看
    String url = Constant.BaseUrl + "getNews";
    final String s = MD5Tools.MD5(MD5Tools.MD5("NEW"));
    OkHttpUtils.post().url(url)
            .addParams("FKEY", s)
            .build()
            .execute(new StringCallback() {
                @Override
                public void onError(Call call, Exception e, int id) {
                }
                @Override
                public void onResponse(String response, int id) {
                    NoticeBean noticeBean = new Gson().fromJson(response.toString(), NoticeBean.class);
                    //result == 1表示请求成功
                    if (noticeBean.getResult()== 1){
                        //判断请求的数据集合是否不为空
                        if (noticeBean.getNews().size()!=0){
                            //不为空,则添加数据
                            adapter.addList(noticeBean.getNews());
                        }else {
                            //为空,则调用adapter里面的方法隐藏FootView
                            adapter.setIsLoadMore();
                        }
                    }
                }
            });
}

}

2.Adapter:

 public class NoticeAdapter extends RecyclerView.Adapter{
private List<NoticeBean.NewsBean> list;
private Context mContext;
    //上拉加载更多布局
public static final int view_Foot = 1;
      //主要布局
public static final int view_Normal = 2;
     //是否隐藏
public boolean isLoadMore = false;

public NoticeAdapter(Context mContext, List<NoticeBean.NewsBean> list) {
    this.list = list;
    this.mContext = mContext;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType ==view_Normal ){
        NoticeItemView noticeItemView = new NoticeItemView(mContext);
        NoticeViewHolder viewHolder = new NoticeViewHolder(noticeItemView);
        return viewHolder;
    }else {
        FootView view = new FootView(mContext);
        FootViewHolder footViewHolder = new FootViewHolder(view);
        return footViewHolder;
    }

}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (position == getItemCount()-1){
        FootView itemView = (FootView) holder.itemView;
        if (isLoadMore){
            itemView.setData();
        }else {
            itemView.setVisibility(View.VISIBLE);

        }
    }else {
        NoticeItemView itemView = (NoticeItemView) holder.itemView;
        itemView.setData(list.get(position));
    }

}

@Override
public int getItemCount() {
    return list.size()+1;
}

@Override
public int getItemViewType(int position) {
    if (position == getItemCount()-1){
        return view_Foot;
    }else {
        return view_Normal;
    }
}

public void addList(List<NoticeBean.NewsBean> news) {
    list.addAll(news);
    notifyDataSetChanged();
}

public void setIsLoadMore() {
    this.isLoadMore = true;
    notifyDataSetChanged();
}

static class NoticeViewHolder extends RecyclerView.ViewHolder {
    public NoticeViewHolder(View itemView) {
        super(itemView);
    }
}
static class FootViewHolder extends RecyclerView.ViewHolder {
    public FootViewHolder(View itemView) {
        super(itemView);
    }
}

}

3.FootView为自定义控件,NoticeItemView和FootView大同小异,就不贴代码了,FootView代码如下

       public class FootView extends RelativeLayout {

@BindView(R.id.foot_view_progressbar)
ProgressBar footViewProgressbar;

public FootView(Context context) {
    this(context, null);
}

public FootView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

private void init() {
    View.inflate(getContext(), R.layout.foot_view, this);
    ButterKnife.bind(this,this);
}

public void setData() {
footViewProgressbar.setVisibility(GONE);
}

}

4.FootView的XML文件:

        <?xml version="1.0" encoding="utf-8"?>
       <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<ProgressBar
    android:id="@+id/foot_view_progressbar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"/>

</LinearLayout>

四.后续会更新源码至GitHub,有兴趣的同学可关注此简书账号MiHomes。