RecyclerView 使用总结(二):RecyclerView的下拉刷新、加载更多

一、实现带”下拉刷新”和”加载更多”的仿ListView的RecyclerView

1、下拉刷新
方法:利用SwipeRefreshLayout来实现,将RecyclerView放在SwipeRefreshLayout中,然后调用SwipeRefreshLayout.setOnRefreshListener()方法就可以了。
布局:

  <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swip_refesh_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        ></android.support.v7.widget.RecyclerView>

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

逻辑代码:

mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        List<String> newDatas = new ArrayList<String>();
                        for (int i = 0; i < 3; i++) {
                            newDatas.add("new" + (i + 1));
                        }

                        //添加更新的数据,更新UI
                        mAdapter.addItems(newDatas);

                        //取消刷新动画
                      mSwipeRefreshLayout.setRefreshing(false);
                    }
                }, 5000);
            }
        });

适配器中应有的方法:

public void addItems(List<String> newDatas) {
        if (newDatas != null) {
            newDatas.addAll(mDatas);
            mDatas.removeAll(mDatas);
            mDatas.addAll(newDatas);
            notifyDataSetChanged();
        }
    }

SwipeRefreshLayout简介:
SwipeRefreshLayout是google官方推出的一个新的Widget,可以实现下拉刷新的效果。该控件继承自ViewGroup在support-v4包下面,不过我们升级supportlibrary的版本到19.1以上,基本使用方法:

  • setOnRefreshListener(OnRefreshListener):添加下拉刷新监听器
  • setRefreshing(boolean):设置是否显示刷新进度条,false-隐藏,true-显示
  • isRefreshing():检测是否处于刷新状态
  • setColorSchemeResources(R.color.color_red…):设置进度条的颜色,最多可以设置四种
  • setProgressBackgroundColorSchemeColor(getResources().getColor(R.color.color_red)):设置进度条背景颜色
  • setProgressViewOffset():设置进度条到顶部的距离等

    到此,RecyclerView的下拉刷新已实现。

    2、加载更多
    思路:我们监听RecyclerView的滑动事件,如果滑动到最底部,则加载更多数据。
    ①判断该RecyclerView是否需要滚动,即子View是否超出了手机屏幕,代码如下:

 private boolean isCouldLoadMore() {
        //获取可以看到的子View的个数
        int visibleItemCount = mRecyclerView.getChildCount();
        //如果可视的子View的个数就是所有的子View,就不需要滚动
        if (visibleItemCount == mAdapter.mDatas.size()) {
            return false;
        }
        return true;
    }

②在适配器中准备加载更多的动画:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    public static final int PULL_TO_MORE = 0;
    public static final int PULLINT_MORE = 1;
    public final static int PULLED_FINISH = 2;

    private final int TYPE_ITEM = 0;
    private final int TYPE_FOOTER = 1;

    //当前的加载状态
    private int current_load_more_state = 0;

    private Context mContext;
    private LayoutInflater mInflater;
    public List<String> mDatas;

    //子view是否充满了手机屏幕
    private boolean isCompleteFill = false;

    public RecyclerViewAdapter(Context context, List<String> datas) {

        this.mContext = context;
        this.mDatas = datas;
        mInflater = LayoutInflater.from(mContext);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder==null){
            return;
        }
        if (holder instanceof ItemViewHolder){
            ((ItemViewHolder) holder).textView.setText(mDatas.get(position));
        }
        else if (holder instanceof FooterViewHolder){

            String msg = "";
            switch (current_load_more_state){
                case PULL_TO_MORE:
                    msg = "上拉加载更多";
                    break;
                case PULLINT_MORE:
                    msg = "正在加载...";
                    break;
                case PULLED_FINISH:
                    //加载完成,初始化
                    current_load_more_state = 0;
                    msg = "上拉加载更多";
                    break;
                default:
                    break;
            }
((FooterViewHolder)holder).footerTextView.setText(msg);
        }

    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        //普通item的view
        if (viewType == TYPE_ITEM) {
            View view = mInflater.inflate(R.layout.item, parent, false);
            ItemViewHolder mItemViewHolder = new ItemViewHolder(view);
            return mItemViewHolder;
        }
        //加载更多的动画
        else if (viewType == TYPE_FOOTER && isCompleteFill) {
            View view = mInflater.inflate(R.layout.add_more_footer, parent, false);
            FooterViewHolder mFooterViewHolder = new FooterViewHolder(view);
            return mFooterViewHolder;
        }
        return null;

    }

    @Override
    public int getItemCount() {
        //如果已经占满了手机屏幕,就把加载更多的布局加在RecyclerView的最后面
        if (isCompleteFill){
            return mDatas.size()+1;
        }
        //否则就去掉加载更多的布局
        else {
            return mDatas.size();
        }
    }

    @Override
    public int getItemViewType(int position) {
       //如果子View还没有占满手机屏幕,或者还没有到最后一个子View,就显示Item的布局
       if (!isCompleteFill || position + 1 != getItemCount()) {
            return TYPE_ITEM;
        } else {
            return TYPE_FOOTER;
        }
    }

    //下拉刷新时,添加数据
    public void addItems(List<String> newDatas) {
        if (newDatas != null) {
            newDatas.addAll(mDatas);
            mDatas.removeAll(mDatas);
            mDatas.addAll(newDatas);
            notifyDataSetChanged();
        }
    }

    //加载更多时,添加数据
    public void addMoreDatas(List<String> moreDatas) {
        if (moreDatas != null) {
            mDatas.addAll(moreDatas);
            current_load_more_state = PULLED_FINISH;
            notifyDataSetChanged();
        }
    }

    class ItemViewHolder extends RecyclerView.ViewHolder {

        protected TextView textView;

        public ItemViewHolder(View itemView) {
            super(itemView);

            textView = (TextView) itemView.findViewById(R.id.text_view);
        }
    }

    class FooterViewHolder extends RecyclerView.ViewHolder {

        private TextView footerTextView;

        public FooterViewHolder(View itemView) {
            super(itemView);

            footerTextView = (TextView) itemView.findViewById(R.id.add_more_state_text);
        }
    }

    //更改加载更多的状态
    public void changeLoadMoreStatus(int status){
        current_load_more_state = status;
        notifyDataSetChanged();
    }
    //更改手机屏幕是否被占满的状态
    public void changeIsCompleteFill(boolean status){
        isCompleteFill = status;
        notifyDataSetChanged();
    }
}

③实现加载更多:

        //监听滚动事件,加载更多数据
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

                if (isCouldLoadMore()) {
                    //子View已占满手机屏幕
                    mAdapter.changeIsCompleteFill(true);
                    //判断是否滚动到最后一个子View
                    if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == mAdapter.getItemCount()) {
                        mAdapter.changeLoadMoreStatus(mAdapter.PULLINT_MORE);
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                List<String> moreDatas = new ArrayList<String>();
                                for (int i = 0; i < 3; i++) {
                                    moreDatas.add("more data" + (i + 1));
                                }
                                mAdapter.addMoreDatas(moreDatas);
                                Toast.makeText(MainActivity.this, "加载完成", Toast.LENGTH_LONG).show();
                            }
                        }, 5000);
                    }
                } else {
                    mAdapter.changeIsCompleteFill(false);
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                lastVisibleItem = mLinearLayoutManager.findLastVisibleItemPosition();
            }
        });

到此,RecyclerView的下拉刷新、加载更多就算实现了。
存在的问题:当子View的总高度小于手机屏幕的高度,且子View+1的总高度大于手机屏幕的高度时,加载更多的布局就会出现显示问题,暂未解决

代码下载请点我

RecyclerView使用总结的全部代码请点这儿

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值