Android RecyclerView 自动加载更多

来源:互联网 发布:windows arp命令事例 编辑:程序博客网 时间:2024/06/11 06:30

老规矩,先上效果图。

1 判断到达底部

首先思考下自动加载更多这个需求,可以知道就是滑动到底部的时候同时加载更多的数据。那么首先需要做的就是判断是否滑动到了底部。

RecyclerView 有个方法onScrolled(int dx, int dy)会在整个滑动过程调用,所以我们可以在这个方法中去判断是否到达底部。

至于要怎么判断呢?

到达底部即是说我们的列表的最底部已经展示了最后一条数据,这一条数据的position我们是知道的,即条目总数-1。

如果我们能获取到滑动过程中,屏幕上显示的最后一条的position,如果它的值等于条目总数-1的话,这个时候就说明已经滑动到最底部了。

看代码:

 @Override public void onScrolled(int dx, int dy) {     super.onScrolled(dx, dy);     //拿到最后一条的position     int endCompletelyPosition = getLayoutManager().     findLastCompletelyVisibleItemPosition();     if (endCompletelyPosition ==getAdapter().getItemCount()-1){         //执行加载更多的方法,无论是用接口还是别的方式都行     } }

我这儿是重写的RecyclerView,如果不想重写,也可以用RecyclerView的addOnScrollListener方法,都差不多的。

2 添加底部的View

大多数情况下,我们加载更多的或者下拉刷新的时候,都要有提示才合理。用ListView的话,可以直接用addFooterView方法,但是RecyclerView没有这个方法,该怎么办呢。

这里有一种方法是根据itemType来判断,如果是最后一条,就添加的是底部View,其余的是正常的View。

需要重写Adapter 里面的 getItemViewType(int position) 方法。

    @Override    public int getItemViewType(int position) {        if (position == getItemCount() - 1){            return ITEM_TYPE_FOOTER;        }else {            return 1;        }    }

然后在onCreateViewHolder方法里面,添加底部View

@Override    public CommonRcViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (viewType == ITEM_TYPE_FOOTER){            View view = 底部View;//可以通过layoutInflater获取            return new CommonRcViewHolder(view);        }elese        return super.onCreateViewHolder(parent, viewType);    }

在onBindViewHolder方法中设置数据的时候也要判断一下

@Overridepublic void onBindViewHolder(CommonRcViewHolder holder, int position) {        if (getItemViewType(position) != ITEM_TYPE_FOOTER){            //加载数据        } }

大体上就是这样了。


这里我自己封装了一个简单的

LoadMoreRecyclerView.java

package cn.demo.videolist.recycler;import android.content.Context;import android.support.annotation.Nullable;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.util.AttributeSet;import android.util.Log;public class LoadMoreRecyclerView extends RecyclerView {    private LinearLayoutManager mLinearLayoutManager;    private LoadMoreAdapter mAdapter;    public LoadMoreRecyclerView(Context context) {        this(context,null);    }    public LoadMoreRecyclerView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs,0);    }    public LoadMoreRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    @Override    public void onScrolled(int dx, int dy) {        super.onScrolled(dx, dy);        int endCompletelyPosition = mLinearLayoutManager.findLastCompletelyVisibleItemPosition();        if (endCompletelyPosition == mAdapter.getItemCount()-1){            mAdapter.loadMore();        }    }    public void setManager(){        mLinearLayoutManager = new LinearLayoutManager(getContext());        setLayoutManager(mLinearLayoutManager);    }    public LinearLayoutManager getLayoutManager() {        return mLinearLayoutManager;    }    public void setLoadMoreAdapter(LoadMoreAdapter mAdapter) {        this.mAdapter = mAdapter;        setAdapter(mAdapter);    }}

LoadMoreAdapter.java

package cn.demo.videolist.recycler;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import cn.demo.videolist.R;public abstract class LoadMoreAdapter extends RecyclerView.Adapter<CommonRcViewHolder> {    public static final int ITEM_TYPE_FOOTER = 0;    protected String loadMoreText = "加载更多";    @Override    public int getItemViewType(int position) {        if (position == getItemCount() - 1){            return ITEM_TYPE_FOOTER;        }else {            return 1;        }    }    @Override    public CommonRcViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (viewType == ITEM_TYPE_FOOTER){            View view = LayoutInflater.from(parent.getContext()).inflate(getFooterViewResId(),parent,false);            return new CommonRcViewHolder(view);        }else {            return getViewHolder(parent,viewType);        }    }    @Override    public void onBindViewHolder(CommonRcViewHolder holder, int position) {        if (getItemViewType(position) != ITEM_TYPE_FOOTER){            loadData(holder, position);        }else {            TextView tv = holder.getView(getFooterTextViewResId());            tv.setText(loadMoreText);        }    }    @Override    public int getItemCount() {        return getCount()+1;    }    public void setLoadMoreText(String loadMoreText) {        this.loadMoreText = loadMoreText;        notifyItemChanged(getItemCount()-1);    }    public abstract int getFooterViewResId();    public abstract int getFooterTextViewResId();    public abstract int getCount();    public abstract CommonRcViewHolder getViewHolder(ViewGroup parent, int viewType);    public abstract void loadData(CommonRcViewHolder holder, int position);    public abstract void loadMore();}

上面用到的一个通用的ViewHolder,当然也可以自己换别的ViewHolder,毕竟我这儿没把点击做进去

CommonRcViewHolder.java

package cn.demo.videolist.recycler;import android.support.v7.widget.RecyclerView;import android.util.SparseArray;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;public class CommonRcViewHolder extends RecyclerView.ViewHolder {    private SparseArray<View> views = new SparseArray<>();    private View view;    public CommonRcViewHolder(View itemView ) {        super(itemView);        view = itemView;    }    public <T extends View> T getView(int viewId){        View v = views.get(viewId);        if (v==null){            v = view.findViewById(viewId);            views.put(viewId, v);        }        return (T)v;    }    public <T extends View> T getViewWithLayoutParams(int viewId,ViewGroup.LayoutParams lp){        View v = views.get(viewId);        if (v==null){            v = view.findViewById(viewId);            v.setLayoutParams(lp);            views.put(viewId,v);        }        return (T)v;    }    public CommonRcViewHolder setText(int viewId,String text){        TextView tv = getView(viewId);        tv.setText(text);        return this;    }}

用法也很简单,关键的几步有

recyclerView = (LoadMoreRecyclerView) findViewById(R.id.recyclerView);        recyclerView.setManager();        final Adapter adapter = new Adapter();        recyclerView.setLoadMoreAdapter(adapter);

重写的Adapter要继承自上面的LoadMoreAdapter

Adapter

      class Adapter extends LoadMoreAdapter{        private LinkedList<String> mData;        public Adapter( ) {            mData = new LinkedList<>();            for (int i = 0; i < 20; i++) {                mData.add("item "+i+"");            }        }        public void addDate(){            for (int i = 0; i < 3; i++) {                mData.addFirst("refresh "+i);            }            recyclerView.getLayoutManager().scrollToPosition(0);            notifyItemRangeInserted(0,3);        }        @Override        public CommonRcViewHolder getViewHolder(ViewGroup parent, int viewType) {            View view = getLayoutInflater().inflate(R.layout.item_recycler, parent,false);            return new CommonRcViewHolder(view);        }        @Override        public void loadData(CommonRcViewHolder holder, int position) {            TextView tv = holder.getView(R.id.tv);            tv.setText(mData.get(position));        }        @Override        public void loadMore() {            int startPosition = getCount();            if (mData.size() < 100) {                for (int i = 0; i < 20; i++) {                    mData.add("more "+i + "");                }                int endPosition = getCount()-1;                notifyItemRangeInserted(startPosition,20);            }else {                setLoadMoreText("没有更多了");            }        }        @Override        public int getFooterViewResId() {            return R.layout.item_footer;        }        @Override        public int getFooterTextViewResId() {            return R.id.tv;        }        @Override        public int getCount() {            return mData.size();        }    }

两个item文件

item_recycler.xml

<?xml version="1.0" encoding="utf-8"?><TextView android:textSize="20sp"    android:textStyle="bold"    android:gravity="center"    android:id="@+id/tv"    android:textColor="#ffffff"    android:layout_width="match_parent"    android:layout_height="50dp"    xmlns:android="http://schemas.android.com/apk/res/android" />

item_footer.xml

<?xml version="1.0" encoding="utf-8"?><TextView android:text="加载更多"    android:textSize="20sp"    android:textStyle="bold"    android:gravity="center"    android:id="@+id/tv"    android:layout_width="match_parent"    android:layout_height="50dp"    xmlns:android="http://schemas.android.com/apk/res/android" />
0 0
原创粉丝点击