美文网首页Android项目实践Android知识点和文章分享
Recycleview实现下拉刷新&上拉加载更多

Recycleview实现下拉刷新&上拉加载更多

作者: MiHomes | 来源:发表于2017-06-02 09:34 被阅读1211次

    一.下拉刷新
    话不多说,前段时间做项目的时候刚用到过,分享出来集思广益,欢迎指出不足。本文主要利用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。

    末尾:移动互联&人力资源交流群,可加微信zy666128入群交流。


    image.png

    相关文章

      网友评论

      • Jsonzhang:你好,楼主,应该有问题吧,就是如果不满一屏也会拉加载吧
        MiHomes:@Jsonzhang 你好,Adapter提供有setIsLoadMore方法来决定什么时候隐藏加载。
      • 恨自己不能小清新:更新到GitHub上了吗 大哥
        MiHomes:@恨自己不能小清新 暂不更,还太浅显。以后优化得更好了会更
      • 65b82d93d900:博主,你这边有个问题,你这样的写法跟我的差不多,你试一下在华为手机,下面有个导航键,点击隐藏的时候,刷新一下,点击显示,又刷新一下,我这边都不知道怎么处理,测试那边一直纠结这个问题
        65b82d93d900:@李智昊 3Q
        545beebd0b5d: @王尊斌 加个监听导航键的函数呗http://m.blog.csdn.net/article/details?id=50786923
      • yyg:上拉刷新呢?
        MiHomes: @yyg 已更新
        MiHomes::wink: 等我调完这个接口就发上拉刷新的
      • clb100:material design使用下拉刷新确实挺简单
        MiHomes: @har的先森 对的

      本文标题:Recycleview实现下拉刷新&上拉加载更多

      本文链接:https://www.haomeiwen.com/subject/vsiyfxtx.html