RecyclerView的使用(4)之下拉刷新和上拉加载

原创文章,转载请注明 http://blog.csdn.net/leejizhou/article/details/50823184 李济洲的博客

这篇介绍下如何为RecyclerView添加下拉刷新和上拉加载,过去在ListView当中添加下拉刷新和上拉加载是非常方便的利用addHeaderView和addFooterView,RecyclerView的刷新同样也是需要靠List当中添加Head或Foot来实现的,如何为RecyclerView添加HeaderView和FooterView参考上一篇博文 http://blog.csdn.net/leejizhou/article/details/50742544 俗话说不要重复发明轮子(PS 还达不到大神们的高度),本篇不会详细告诉你怎么去做一个下拉刷新和加载的效果,而是如何快速利用现有的知名开源库来为RecyclerView实现下面的效果。

先看下DEMO效果
RecyclerView的使用(4)之下拉刷新和上拉加载_第1张图片

这个下拉刷新不是靠List当中添加HeaderView来实现的,而是在RecyclerView外面套了一层ViewGroup而这个ViewGroup支持下拉刷新,可以灵巧的实现一些子View的下拉刷新,这个就是大名鼎鼎的android-Ultra-Pull-To-Refresh开源库,作者liaohuqiu,但是很遗憾它不支持上拉加载,本篇用的是在这个库基础上进行了拓展并实现了上拉加载效果的开源库,上拉的效果实现是靠RecyclerView里添加FooterView,Github地址:https://github.com/Chanven/CommonPullToRefresh 感谢活跃在开源社区的开发者们。

具体的实现步骤:(开发工具:Android Studio)

1:Gradle配置 build.gradle

//可选 或者在上面地址中下载library源代码copy到项目里面
compile 'com.chanven.lib:cptr:1.0.0' 

// RecyclerView和CardView
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:cardview-v7:23.1.1'

2:主布局文件 activity_main.xml 里面一个RecyclerView 外面嵌套的是支持下拉刷新的ViewGroup

"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.chanven.lib.cptr.PtrClassicFrameLayout
        android:id="@+id/rotate_header_list_view_frame"
        xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#e1e1e1"
        cube_ptr:ptr_duration_to_close="200"
        cube_ptr:ptr_duration_to_close_header="1000"
        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">
        .support.v7.widget.RecyclerView
            android:background="#ffffff"
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/rv_list"
            />

    com.chanven.lib.cptr.PtrClassicFrameLayout>

3:列表项布局 rv_item.xml 外面一个CardView的卡片式容器,里面一个TextView


<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:id="@+id/cv_item"
    android:foreground="?android:attr/selectableItemBackground"
    card_view:cardCornerRadius="4dp"
    card_view:cardElevation="4dp"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv_item_text"
            android:text="test"
            android:layout_margin="8dp"
            />
    LinearLayout>

android.support.v7.widget.CardView>

4:RecyclerView的Adapter RvAdapter.java
如果还不了解RecyclerView使用 请参考 http://blog.csdn.net/leejizhou/article/details/50670657

/**
 * 李济洲的博客
 * Blog:http://blog.csdn.net/leejizhou
 * QQ: 3107777777
 */
public class RvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private LayoutInflater mLayoutInflater;
    private Context mContext;
    private List  mTitle;


    public RvAdapter(Context context,List title){
        mContext=context;
        mTitle=title;
        mLayoutInflater=LayoutInflater.from(context);

    }
    //自定义的ViewHolder,持有每个Item的的所有界面元素
    public  static class NormalViewHolder extends RecyclerView.ViewHolder {
        TextView mTextView;
        CardView mCardView;

        public NormalViewHolder(View itemView) {
            super(itemView);
            mTextView=(TextView)itemView.findViewById(R.id.tv_item_text);
            mCardView=(CardView)itemView.findViewById(R.id.cv_item);

        }



    }
    //在该方法中我们创建一个ViewHolder并返回,ViewHolder必须有一个带有View的构造函数,这个View就是我们Item的根布局,在这里我们使用自定义Item的布局;
    @Override
    public NormalViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        return new NormalViewHolder(mLayoutInflater.inflate(R.layout.rv_item,parent,false));
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        NormalViewHolder viewholder = (NormalViewHolder) holder;
           viewholder.mTextView.setText(mTitle.get(position));

    }


    //获取数据的数量
    @Override
    public int getItemCount() {
        return mTitle==null ? 0 : mTitle.size();
    }
}

5:最重要的Activity的实现,MainActivity.java,代码含义已经注释

/**
 * 李济洲的博客
 * Blog:http://blog.csdn.net/leejizhou
 * QQ: 3107777777
 */
public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    //支持下拉刷新的ViewGroup
    private PtrClassicFrameLayout mPtrFrame;
    //List数据
    private List title = new ArrayList<>();
    //RecyclerView自定义Adapter
    private RvAdapter adapter;
    //添加Header和Footer的封装类
    private RecyclerAdapterWithHF mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRecyclerView = (RecyclerView) findViewById(R.id.rv_list);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(layoutManager);

        adapter = new RvAdapter(MainActivity.this, title);
        mAdapter = new RecyclerAdapterWithHF(adapter);

        mRecyclerView.setAdapter(mAdapter);

        mPtrFrame = (PtrClassicFrameLayout) findViewById(R.id.rotate_header_list_view_frame);
        //下拉刷新支持时间
        mPtrFrame.setLastUpdateTimeRelateObject(this);
        //下拉刷新一些设置 详情参考文档
        mPtrFrame.setResistance(1.7f);
        mPtrFrame.setRatioOfHeaderHeightToRefresh(1.2f);
        mPtrFrame.setDurationToClose(200);
        mPtrFrame.setDurationToCloseHeader(1000);
        // default is false
        mPtrFrame.setPullToRefresh(false);
        // default is true
        mPtrFrame.setKeepHeaderWhenRefresh(true);
        //进入Activity就进行自动下拉刷新
        mPtrFrame.postDelayed(new Runnable() {
            @Override
            public void run() {
                mPtrFrame.autoRefresh();
            }
        }, 100);

        //下拉刷新
        mPtrFrame.setPtrHandler(new PtrDefaultHandler() {


            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                title.clear();
                //模拟数据
                for (int i = 0; i <= 5; i++) {
                    title.add(String.valueOf(i));
                }
                //模拟联网 延迟更新列表
                new Handler().postDelayed(new Runnable() {
                    public void run() {
                        mAdapter.notifyDataSetChanged();
                        mPtrFrame.refreshComplete();
                        mPtrFrame.setLoadMoreEnable(true);

                    }
                }, 1000);


            }
        });
        //上拉加载
        mPtrFrame.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void loadMore() {

                //模拟联网延迟更新数据
                new Handler().postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        //模拟数据
                        for (int i = 0; i <= 5; i++) {
                            title.add(String.valueOf(i));
                        }
                        mAdapter.notifyDataSetChanged();
                        mPtrFrame.loadMoreComplete(true);
                        Toast.makeText(MainActivity.this, "load more complete", Toast.LENGTH_SHORT)
                                .show();
                    }
                }, 1000);


            }
        });




    }
}

Ok,RecyclerView的下拉刷新和上拉加载就快速实现了,本篇Demo的源码下载地址 http://download.csdn.net/detail/leejizhou/9455043 有什么问题也可以在下方留言,感谢大家的支持。

你可能感兴趣的:(android开发)