RecyclerView(三)——为RecyclerView增加下拉刷新和加载更多功能

来源:互联网 发布:python 中英文混合 编辑:程序博客网 时间:2024/05/18 20:11

  很简单,本文实现两个功能:
  - 下拉刷新
  - 加载更多

  之前看过大部分的博客,都是利用SwipeRefreshLayout的setOnRefreshListener方法实现下拉刷新,利用RecyclerView的addOnScrollListener方法实现加载更多。这样子,下拉刷新的功能是没问题的,但是加载更多的功能有一个弊端就是如果刚进页面的第一次加载的数据如果没有占满全屏的话,那么此RecyclerView就滑动不了了,因此也就没法去调用addOnScrollListener里面的代码了。为了解决这个问题,我们可以在适当的时候为recyclerView增加一个FooterView,让其在不能滑动的时候还能够通过点击来执行加载更多的操作。
为RecyclerView增加FooterView可以查看这一篇博客http://blog.csdn.net/yql_running/article/details/70914999

接下来,直接上代码

view_footer_load_more.xml  FooterView的界面布局文件

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/text_view"    android:layout_width="match_parent"    android:layout_height="46dp"    android:gravity="center"    android:text="点击加载更多" />

RecyclerSimpleAdapter. java

package com.zou.zohar.recyclerviewdemo.ui.adapter;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;import com.zou.zohar.recyclerviewdemo.R;import java.util.List;/** * desc:简单的RecyclerView适配器 * Created by Zohar on 2017/4/7. */public class RecyclerSimpleAdapter extends RecyclerView.Adapter<RecyclerSimpleAdapter.ViewHolder> {    private List<String> dates = null;    public RecyclerSimpleAdapter(List<String> dates) {        this.dates = dates;    }    @Override    public RecyclerSimpleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_layout, parent, false);        return new ViewHolder(view);    }    @Override    public void onBindViewHolder(final RecyclerSimpleAdapter.ViewHolder holder, final int position) {        holder.textView.setText(dates.get(position));    }    @Override    public int getItemCount() {        return dates.size();    }    class ViewHolder extends RecyclerView.ViewHolder {        LinearLayout llMain;        TextView textView;        ViewHolder(View itemView) {            super(itemView);            llMain = (LinearLayout) itemView.findViewById(R.id.ll_main);            textView = (TextView) itemView.findViewById(R.id.text);        }    }}

RecyclerViewHeaderFooterWrapper.java

package com.zou.zohar.recyclerviewdemo.ui.adapter;import android.support.v4.util.SparseArrayCompat;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;import android.view.ViewGroup;/** * desc: * Created by Zohar on 2017/4/27. */public class RecyclerViewHeaderFooterWrapper extends RecyclerView.Adapter {    //BASE_ITEM_TYPE_HEADER 和 BASE_ITEM_TYPE_FOOTER 没有什么特殊的含义,    //只是用作将HeaderView和FooterView存放在SparseArrayCompat<View>容器中时的key值,方便取用    //具体使用见 addHeaderView(View view) 和 getItemViewType(int position) 以及 onCreateViewHolder(ViewGroup parent, int viewType) 方法    private static final int BASE_ITEM_TYPE_HEADER = 100000;    private static final int BASE_ITEM_TYPE_FOOTER = 200000;    private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();//HeaderView的集合    private SparseArrayCompat<View.OnClickListener> mHeaderViewClickListeners = new SparseArrayCompat<>();//HeaderView监听事件的集合    private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>();//FooterView的集合    private SparseArrayCompat<View.OnClickListener> mFootViewClickListeners = new SparseArrayCompat<>();//FooterView监听事件的集合    private RecyclerView.Adapter mAdapter;//控制内容item的Adapter    public RecyclerViewHeaderFooterWrapper(RecyclerView.Adapter adapter) {        mAdapter = adapter;    }    /**     * Returns true if the item is HeaderView     *     * @param position position of the item to be examined     * @return true if item is HeaderView     */    private boolean isHeaderView(int position) {        return position < getHeadersCount();    }    /**     * Returns true if the item is FooterView     *     * @param position position of the item to be examined     * @return true if item is FooterView     */    private boolean isFooterView(int position) {        return position >= getHeadersCount() + getRealItemCount();    }    /**     * add a headerView     *     * @param view headerView     */    public void addHeaderView(View view) {        addHeaderView(view, null);    }    /**     * add a headerView with clickListener     *     * @param view     headerView     * @param listener clickListener     */    public void addHeaderView(View view, View.OnClickListener listener) {        if (listener != null) {            mHeaderViewClickListeners.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, listener);        }        mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view);    }    /**     * add a footerView     *     * @param view footerView     */    public void addFootView(View view) {        addFootView(view, null);    }    /**     * add a footerView with clickListener     *     * @param view     footerView     * @param listener clickListener     */    public void addFootView(View view, View.OnClickListener listener) {        if (listener != null) {            mFootViewClickListeners.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, listener);        }        mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view);    }    /**     * get the count of headers     *     * @return headersCount     */    public int getHeadersCount() {        return mHeaderViews.size();    }    /**     * get the count of footers     *     * @return footersCount     */    public int getFootersCount() {        return mFootViews.size();    }    /**     * get the count of items without headers and footers     *     * @return real itemsCount     */    private int getRealItemCount() {        return mAdapter.getItemCount();    }    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (mHeaderViews.get(viewType) != null) {            ViewHolder holder = new ViewHolder(mHeaderViews.get(viewType));            if (mHeaderViewClickListeners.get(viewType) != null) {                holder.itemView.setOnClickListener(mHeaderViewClickListeners.get(viewType));            }            return holder;        } else if (mFootViews.get(viewType) != null) {            RecyclerView.ViewHolder holder = new ViewHolder(mFootViews.get(viewType));            if (mFootViewClickListeners.get(viewType) != null) {                holder.itemView.setOnClickListener(mFootViewClickListeners.get(viewType));            }            return holder;        }        return mAdapter.onCreateViewHolder(parent, viewType);    }    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        if (isHeaderView(position)) {            return;        }        if (isFooterView(position)) {            return;        }        mAdapter.onBindViewHolder(holder, position - getHeadersCount());    }    @Override    public int getItemCount() {        return getHeadersCount() + getFootersCount() + getRealItemCount();    }    @Override    public int getItemViewType(int position) {        if (isHeaderView(position)) {            return mHeaderViews.keyAt(position);        } else if (isFooterView(position)) {            return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());        }        return mAdapter.getItemViewType(position - getHeadersCount());    }    @Override    public void onAttachedToRecyclerView(RecyclerView recyclerView) {        mAdapter.onAttachedToRecyclerView(recyclerView);        final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;            final GridLayoutManager.SpanSizeLookup oldLookup = gridLayoutManager.getSpanSizeLookup();            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {                @Override                public int getSpanSize(int position) {                    int viewType = getItemViewType(position);                    if (mHeaderViews.get(viewType) != null) {                        return ((GridLayoutManager) layoutManager).getSpanCount();                    } else if (mFootViews.get(viewType) != null) {                        return ((GridLayoutManager) layoutManager).getSpanCount();                    }                    if (oldLookup != null) {                        return oldLookup.getSpanSize(position);                    }                    return 1;                }            });            gridLayoutManager.setSpanCount(gridLayoutManager.getSpanCount());        }    }    private class ViewHolder extends RecyclerView.ViewHolder {        ViewHolder(View itemView) {            super(itemView);        }    }}

RefreshAndLoadMoreActivity.java

package com.zou.zohar.recyclerviewdemo.ui.activity;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.v4.widget.SwipeRefreshLayout;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.DividerItemDecoration;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import com.zou.zohar.recyclerviewdemo.R;import com.zou.zohar.recyclerviewdemo.ui.adapter.RecyclerSimpleAdapter;import com.zou.zohar.recyclerviewdemo.ui.adapter.RecyclerViewHeaderFooterWrapper;import java.util.ArrayList;import java.util.List;public class RefreshAndLoadMoreActivity extends AppCompatActivity {    private List<String> dataList = new ArrayList<>();    private SwipeRefreshLayout refreshLayout;    private RecyclerView recyclerView;    private LinearLayoutManager layoutManager;    private RecyclerSimpleAdapter simpleAdapter;    private RecyclerViewHeaderFooterWrapper wrapper;    private boolean isLoading = false;//true:is loading data    private int page;//页码    private int pageCount = 10;//每页的条数    private int refreshTimes = 0;//刷新的次数    //刷新数据的Handler    private Handler refreshHandler = new Handler(Looper.myLooper()) {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            refreshTimes++;            clearData();            initData();            refreshLayout.setRefreshing(false);        }    };    //加载更多的Handler    private Handler loadMoreHandler = new Handler(Looper.myLooper()) {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            isLoading = true;            //此时是刷新状态            initData();            wrapper.notifyDataSetChanged();            isLoading = false;        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_refresh_by_swipe);        refreshLayout = (SwipeRefreshLayout) findViewById(R.id.main_layout);        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);        initData();        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));        layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);        recyclerView.setLayoutManager(layoutManager);        simpleAdapter = new RecyclerSimpleAdapter(dataList);//原本的Adapter        wrapper = new RecyclerViewHeaderFooterWrapper(simpleAdapter);        wrapper.addFootView(createLoadMoreView());        recyclerView.setAdapter(wrapper);        //下拉监听        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {            @Override            public void onRefresh() {                new Thread(new Runnable() {                    @Override                    public void run() {                        refreshHandler.sendEmptyMessageAtTime(1, 2000);                    }                }).start();            }        });        //加载更多        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                super.onScrollStateChanged(recyclerView, newState);                // SCROLL_STATE_IDLE 表示当前并不处于滑动状态                // SCROLL_STATE_DRAGGING 表示当前RecyclerView处于滑动状态(手指在屏幕上)                // SCROLL_STATE_SETTLING 表示当前RecyclerView处于滑动状态(手已经离开屏幕)                if (newState == RecyclerView.SCROLL_STATE_IDLE) {                    int totalItemCount = layoutManager.getItemCount();                    int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();                    if (!isLoading && lastVisibleItemPosition == (totalItemCount - 1) && dataList.size() < 100) {                        loadMoreData();                    }                }            }            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);            }        });    }    private void loadMoreData() {        new Thread(new Runnable() {            @Override            public void run() {                loadMoreHandler.sendEmptyMessageAtTime(1, 2000);            }        }).start();    }    private View createLoadMoreView() {        LayoutInflater inflater = LayoutInflater.from(this);        View view = inflater.inflate(R.layout.view_footer_load_more, recyclerView, false);        view.findViewById(R.id.text_view).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                loadMoreData();            }        });        return view;    }    /**     * 增加一页数据     */    private void initData() {        page++;        for (int i = 1; i <= pageCount; i++) {            if (i == 1) {                dataList.add(String.valueOf(i + pageCount * (page - 1)) + "(第" + page + "页)," + "刷新了" + refreshTimes + "次");            } else {                dataList.add(String.valueOf(i + pageCount * (page - 1)));            }        }    }    /**     * 清楚数据     */    private void clearData() {        page = 0;        dataList.clear();    }}
1 0
原创粉丝点击