RecyclerView的上拉加载更多

@2016/03/02更新:

引入下拉刷新 android-Ultra-Pull-To-Refresh

SwipeRefreshLayout组件支持了下拉刷新,在这个基础上改造RecyclerView上拉加载更多。

实现思路:

  1. listView加个底部view(footer_view)
  2. 在listview到底部的时候,自动加载。
  3. footer_view 展示提示文字和加载状态(菊花)

增加一个footer_view.xml

1.MaterialProgressBarSupport:从SwipeRefreshLayout组件中抠出来的,用作加载的转菊花。
2.一行文字提示
3.居中

<?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="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="horizontal">

    <LinearLayout android:layout_width="wrap_content" android:layout_height="40dp" android:layout_centerHorizontal="true">

        <com.github.captain_miao.recyclerviewutils.MaterialProgressBarSupport android:id="@+id/progress_view" android:layout_width="40dp" android:layout_height="40dp" app:progressColor="@color/progress_bar_color" app:progressBackgroundColor="@color/progress_bar_background_light" app:progressSmallSize="true"/>

        <TextView android:id="@+id/tv_content" android:paddingLeft="8dp" android:layout_width="wrap_content" android:layout_height="40dp" android:gravity="center_vertical" android:text="@string/app_loading_more" />
    </LinearLayout>
</RelativeLayout>

RecyclerView.Adapter增加一个底部view(footer_view)

1. 定义一个FOOTER_TYPE
2. 实现FOOTER_TYPE的onCreateViewHolder
3. 实现FOOTER_TYPE的onBindViewHolder
4. 留出item的onCreateViewHolder接口:abstract VH onCreateItemViewHolder()
5. 留出item的onBindViewHolder接口:abstract void onBindItemViewHolder()

    //footer_view 的 ViewHolder
    public static class FooterViewHolder extends RecyclerView.ViewHolder {
        public final MaterialProgressBarSupport mProgressView;
        public final TextView mTextView;

        public FooterViewHolder(View view) {
            super(view);
            mProgressView = (MaterialProgressBarSupport) view.findViewById(R.id.progress_view);
            mTextView = (TextView) view.findViewById(R.id.tv_content);
        }

        @Override
        public String toString() {
            return super.toString() + " '" + mTextView.getText();
        }
    }


    //数据itemViewHolder 实现
    public abstract VH onCreateItemViewHolder(ViewGroup parent, int viewType);

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType == TYPE_FOOTER){//底部 加载view
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_view_load_more, parent, false);
            return new FooterViewHolder(view);
        } else {
            //数据itemViewHolder
            return onCreateItemViewHolder(parent, viewType);
        }
    }

    //数据itemViewHolder 实现
    public abstract void onBindItemViewHolder(final VH holder, int position);

    @Override
    @SuppressWarnings("unchecked")
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        if(holder instanceof FooterViewHolder) {
            //没有更多数据
            if(hasMoreData){
                ((FooterViewHolder) holder).mProgressView.setVisibility(View.VISIBLE);
                ((FooterViewHolder) holder).mProgressView.startProgress();
                //((FooterViewHolder) holder).mProgressView.setIndeterminate(true);
                ((FooterViewHolder) holder).mTextView.setText(R.string.app_loading_more);
            } else {
                ((FooterViewHolder) holder).mProgressView.stopProgress();
                ((FooterViewHolder) holder).mProgressView.setVisibility(View.GONE);
                //((FooterViewHolder) holder).mProgressView.st;
                ((FooterViewHolder) holder).mTextView.setText(R.string.app_no_more_data);
            }
        } else {
            onBindItemViewHolder((VH)holder, position);
        }
    }

    @Override
    public int getItemViewType(int position) {

        if (position == getBasicItemCount() &amp;&amp; hasFooter) {
            return TYPE_FOOTER;
        }
        return super.getItemViewType(position);//0
    }

RecyclerView增加一个到达底部监听

public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
    private int previousTotal = 0; // The total number of items in the dataset after the last load
    private boolean loading = false;
    //list到达 最后一个item的时候 触发加载
    private int visibleThreshold = 1;
    // The minimum amount of items to have below your current scroll position before loading more.
    int firstVisibleItem, visibleItemCount, totalItemCount;
    //默认第一页
    private int current_page = 1;

    private LinearLayoutManager mLinearLayoutManager;

    public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
        this.mLinearLayoutManager = linearLayoutManager;
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        visibleItemCount = recyclerView.getChildCount();
        totalItemCount = mLinearLayoutManager.getItemCount();
        firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();

        //判断加载完成了...
        if (loading) {
            if (totalItemCount &gt; previousTotal) {
                loading = false;
                previousTotal = totalItemCount;
            }
        }
        if (!loading &amp;&amp; totalItemCount &gt;visibleItemCount &amp;&amp; (totalItemCount - visibleItemCount) &lt;= (firstVisibleItem + visibleThreshold)) {
            current_page++;
            onLoadMore(current_page);
            loading = true;
        }
    }

    public abstract void onLoadMore(int current_page);
}

RecyclerView中使用

        mRecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(mLinearLayoutManager) {
            @Override
            public void onLoadMore(int current_page) {
                mAdapter.setHasFooter(true);
                //do something
            }
        });
    //RecyclerViewAdapter 实现
    public static class SimpleStringRecyclerViewAdapter
            extends BaseLoadMoreRecyclerAdapter&lt;String, ItemViewHolder&gt; {

        public SimpleStringRecyclerViewAdapter(Context context, List&lt;String&gt; items) {
            appendToList(items);
        }


        @Override
        public ItemViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.list_item, parent, false);
            return new ItemViewHolder(view);
        }

        @Override
        public void onBindItemViewHolder(ItemViewHolder holder, int position) {
            holder.mTextView.setText(getItem(position));
            holder.mImageView.setImageResource(R.mipmap.ic_launcher);
        }
    }

load_more

搞定收工

GitHub地址:

GitHub地址:RecyclerViewUtils

RecyclerView的上拉加载更多》有10个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注