RecyclerView 下拉刷新和上拉加载(一)

今天总结一下RecyclerView 使用LinearLayoutManager的下拉刷新和上拉加载。
下拉刷新参考网址:github地址https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh

关于下拉刷新结合上拉加载的更多的例子请参考这个网址:
https://github.com/shucc/RecyclerViewDemo
我所做的只是通过学习上面的内容自己做一些总结。先看看效果
这里写图片描述

以上就是效果,接下来看代码
1,定义两个接口OnLoadMoreListener.java和OnItemClickListener.java

**
 * 用来处理加载更多事件
 */
public interface OnLoadMoreListener {
    void onLoadMore();
}

/**
 * 用来处理点击事件
 */
public interface OnItemClickListener {
    void onItemClick(View view, int position);
}

2自定义抽象类 MyLoadMoreAdapter 继承自RecyclerView.Adapter

package com.example.loadmoredemo;

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.LinearLayout;
import android.widget.TextView;

/**
 * Created by Administrator on 2016/8/10.
 */
public abstract class MyLoadMoreAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    protected static final int LOAD_MORE_ITEM = -100;
    private RecyclerView mRecyclerView;
    private OnLoadMoreListener onLoadMoreListener;
    private boolean loading = true;
    private int visibleThreshold = 1;
    private int lastVisibleItem, totalItemCount;
    //正在加载中item position
    private int loadMorePos = -1;

    //是否全部加载完成
    private boolean isLoadAll = false;
//加载更多的ViewHolder
    private FootViewHolder footViewHolder;
    private OnItemClickListener onItemClickListener;

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public MyLoadMoreAdapter(RecyclerView recyclerView, final OnLoadMoreListener onloadMoreListener) {
        this.mRecyclerView = recyclerView;
        this.onLoadMoreListener = onloadMoreListener;
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof LinearLayoutManager) {
            final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    totalItemCount = linearLayoutManager.getItemCount();
                    lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
                    if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)
                            && dy > 0 && !isLoadAll) {
                        loading = true;
                        loadMorePos = getItemCount() - 1;
                        notifyItemInserted(getItemCount() - 1);
                        if (onLoadMoreListener != null) {
                            onLoadMoreListener.onLoadMore();
                        }
                    }
                }
            });
        } else {
            //其他的layoutManger
        }

    }

    public final void reset() {
        loading = false;
        if (loadMorePos != -1) {
            notifyItemRemoved(loadMorePos);
        } else {
            notifyDataSetChanged();
        }
    }

    /**
     * 判读数据是否加载完毕,显示不同的布局
     * @param loadAll
     */
    public final void setLoadAll(boolean loadAll) {
        if (footViewHolder == null) {
            View view = LayoutInflater.from(mRecyclerView.getContext()).inflate(R.layout.footer_view_load_more, null);
            footViewHolder = new FootViewHolder(view);
        }
        isLoadAll = loadAll;
        if (isLoadAll && footViewHolder != null) {
            footViewHolder.mLLLoadNow.setVisibility(View.INVISIBLE);
            footViewHolder.mTxtLoadMore.setVisibility(View.VISIBLE);
        } else if (footViewHolder != null) {
            footViewHolder.mLLLoadNow.setVisibility(View.VISIBLE);
            footViewHolder.mTxtLoadMore.setVisibility(View.INVISIBLE);
        }
        if (!isLoadAll) {
            loadMorePos = -1;
        }
    }

    /**
     * 如果position大于List的大小,说明正在加载
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        if (position >= getDataSize()) {
            return LOAD_MORE_ITEM;
        }
        return super.getItemViewType(position);
    }

    //抽象出一个方法用来返回和adapter绑定的List的size的大小
    abstract int getDataSize();

    @Override
    public int getItemCount() {
        if (loading) {
            //如果正在加载更多 返回List.size()+1
            return getDataSize() + 1;
        }
        return getDataSize();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (footViewHolder == null) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.footer_view_load_more, parent, false);
            footViewHolder = new FootViewHolder(view);
        }
        return footViewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        //在这里处理RecyclerView的item的点击事件
        if (!(holder instanceof FootViewHolder) && onItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onItemClickListener.onItemClick(view, position);
                }
            });
        }
    }

    /**
     * 底部加载的布局
     */
    protected class FootViewHolder extends RecyclerView.ViewHolder {

        private LinearLayout mLLLoadNow;
        private TextView mTxtLoadMore;

        public FootViewHolder(View itemView) {
            super(itemView);
            mLLLoadNow = (LinearLayout) itemView.findViewById(R.id.footer_view_load_now);
            mTxtLoadMore = (TextView) itemView.findViewById(R.id.footer_view_load_all);
        }
    }
}

3 定义一个MyAdapter继承自 MyLoadMoreAdapter。内部的实现很简单,就不写注释了

package com.example.loadmoredemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

/**
 * Created by Administrator on 2016/8/10.
 */
public class MyAdapter extends MyLoadMoreAdapter {

    List<String> dataList;
    private Context context;

    public MyAdapter(RecyclerView recyclerView, List<String> list, OnLoadMoreListener onloadMoreListener) {
        super(recyclerView, onloadMoreListener);
        this.dataList = list;
        Log.e("tag","dataList.size()"+dataList.size());
        context = recyclerView.getContext();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == LOAD_MORE_ITEM) {
            return super.onCreateViewHolder(parent, viewType);
        } else {
            View itemView = LayoutInflater.from(context).inflate(R.layout.item, parent, false);
            return new MyHolder(itemView);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof MyHolder && position < dataList.size()) {
            ((MyHolder) holder).textView.setText(dataList.get(position));
        }
    }

    @Override
    int getDataSize() {
        if (dataList == null) {
            return 0;
        } else {
            return dataList.size();
        }
    }

    class MyHolder extends RecyclerView.ViewHolder {

        TextView textView;

        public MyHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.textView);
        }
    }
}

4MainActivity 的 布局文件,涉及下拉刷新控件PtrClassicFrameLayout的使用,引入很简单,在你的module 的build.gradle 文件中加上一行

compile 'in.srain.cube:ultra-ptr:1.0.11'

MainActivity 的 布局文件

<?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">

    <in.srain.cube.views.ptr.PtrClassicFrameLayout xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
        android:id="@+id/myPtrFrameLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        cube_ptr:ptr_duration_to_close="300"
        cube_ptr:ptr_duration_to_close_header="2000"
        cube_ptr:ptr_keep_header_when_refresh="true"
        cube_ptr:ptr_pull_to_fresh="false"
        cube_ptr:ptr_ratio_of_header_height_to_refresh="1.2"
        cube_ptr:ptr_resistance="1.7">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/textView" />

    </in.srain.cube.views.ptr.PtrClassicFrameLayout>
</RelativeLayout>

在代码中实现下拉刷新和上拉加载

package com.example.loadmoredemo;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

import in.srain.cube.views.ptr.PtrClassicFrameLayout;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;

public class MainActivity extends AppCompatActivity {

    MyAdapter adapter;
    List<String> dataList = new ArrayList<>();
    RecyclerView recyclerView;
    int page = 1;
    PtrClassicFrameLayout ptrFrameLayout;//下拉刷新控件

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        ptrFrameLayout = (PtrClassicFrameLayout) findViewById(R.id.myPtrFrameLayout);
        ptrFrameLayout.setPtrHandler(new PtrDefaultHandler() {
            //检查是否可以刷新
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                return PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
            }

            //下拉刷新的时候会调用这个方法,每次下拉刷新都要把page重置为1
            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                page = 1;
                if (adapter != null) {
                    adapter.setLoadAll(false);
                }
                getData();
            }
        });
        /**
         * 延迟500毫秒后ptrFrameLayout自动刷新会调用checkCanDoRefresh(PtrFrameLayout frame, View content, View header)
         * 检查是否可以刷新,如果可以,就调用onRefreshBegin(PtrFrameLayout frame)
         */
        ptrFrameLayout.postDelayed(new Runnable() {
            @Override
            public void run() {
                ptrFrameLayout.autoRefresh();
            }
        }, 500);
    }

    /**
     * 给recyclerView设置适配器
     */
    public void setAdapter() {
        Log.e("tag", "size" + dataList.size());
        if (adapter == null) {
            adapter = new MyAdapter(recyclerView, dataList, new OnLoadMoreListener() {
                @Override
                public void onLoadMore() {
                    //每次上拉加载更多之前要把page++
                    page++;
                    //每次上拉加载更多之前设置setLoadAll(false)
                    if (adapter != null) {
                        adapter.setLoadAll(false);
                    }
                    getData();
                }
            });
            recyclerView.setAdapter(adapter);
        }
        //更新适配器
        adapter.reset();
        //如果正在下拉刷新的话,结束下拉刷新
        if (ptrFrameLayout.isRefreshing()) {
            ptrFrameLayout.refreshComplete();
        }
    }

    public void getData() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (page == 1) {
                    dataList.clear();
                    for (int i = 0; i < 25; i++) {
                        dataList.add("string" + i);
                    }
                    setAdapter();
                } else {
                    if (page > 3) {
                        if (adapter != null) {
                            adapter.setLoadAll(true);
                        }
                    } else {
                        for (int i = 22; i < 33; i++) {
                            dataList.add("string" + i);
                        }
                        setAdapter();
                    }
                }
            }
        }, 2000);


    }
}

以上就实现了RecyclerView 的下拉刷新和上拉加载,关于上拉加载和下拉刷新的更好的实现请移步:https://github.com/Chanven/CommonPullToRefresh

总结:对于recyclerView很多原理理解的还不是很深刻,以后会继续研究。附上代码下载地址:http://download.csdn.net/detail/leilifengxingmw/9606117

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值