RecyclerView+SwipeRefreshLayout实现下拉刷新与上拉加载

LRecyclerViewActivity.java

/**
 * <p> </p>
 * Created by 行走的老者 on 2017/11/13 0013.
 */
public class LRecyclerViewActivity extends AppCompatActivity {
    private LRecyclerView mLRecyclerView;
    private TestAdapter mTestAdapter;
    private SwipeRefreshLayout mRefreshLayout;

    private List<String> mDataList;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lrecycler_view);

        mLRecyclerView = findViewById(R.id.recycler_view);
        mRefreshLayout = findViewById(R.id.switch_refresh);

        mLRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mTestAdapter = new TestAdapter();
        mLRecyclerView.setAdapter(mTestAdapter);

        mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                if (mLRecyclerView.isLoading()) {
                    mRefreshLayout.setRefreshing(false);
                    return;
                }

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mRefreshLayout.setRefreshing(false);
                                mDataList.add(0, "刷新.出来的数据.....");
                                mTestAdapter.setDataList(mDataList);
                            }
                        });
                    }
                }).start();
            }
        });


        mDataList = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            mDataList.add("第一页加载......" + i);
        }
        mTestAdapter.setDataList(mDataList);

        mLRecyclerView.setOnLoadingListener(new LRecyclerView.OnLoadingListener() {
            @Override
            public void onLoading() {
                if (mRefreshLayout.isRefreshing()) return;

                mTestAdapter.setStatus(LoadingAdapter.STATUS_LOADING);
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mLRecyclerView.finishLoading();
                                mTestAdapter.setStatus(LoadingAdapter.STATUS_LOADED);

                                Log.i("liao", "......................mPage=" + mPage);
                                if (mPage > 4) {
                                    Toast.makeText(LRecyclerViewActivity.this, "没有更多数据了", Toast.LENGTH_SHORT).show();
                                    return;
                                }
                                mPage++;

                                for (int i = 0; i < 50; i++) {
                                    mDataList.add("上拉加载.出来的数据....." + i);
                                }
                                mTestAdapter.setDataList(mDataList);
                            }
                        });
                    }
                }).start();
            }
        });
    }

    private int mPage = 1;


    public class TestAdapter extends LoadingAdapter<String> {

        @Override
        public RecyclerView.ViewHolder onCreateHolder(ViewGroup parent, int viewType) {
            return new ItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false));
        }

        @Override
        protected void onBindHolder(RecyclerView.ViewHolder holder, int position) {
            if (holder instanceof ItemViewHolder) {
                ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
                itemViewHolder.mTextView.setText(mDataList.get(position));
            }
        }

        public class ItemViewHolder extends RecyclerView.ViewHolder {
            TextView mTextView;

            public ItemViewHolder(View itemView) {
                super(itemView);
                mTextView = itemView.findViewById(R.id.text);
            }
        }
    }
}

xml资源

activity_lrecycler_view.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/switch_refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <cn.jhworks.demo.loading.LRecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"/>
</android.support.v4.widget.SwipeRefreshLayout>

item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="60dp">

    <TextView
        android:id="@+id/text"
        android:gravity="center"
        android:text="helll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

下面是上拉加载实现

实现见代码:

LRecyclerView .java

/**
 * <p> </p>
 * Created by 行走的老者 on 2017/11/13 0013.
 */
public class LRecyclerView extends RecyclerView {

    private boolean mIsLoading = false;
    private int initPreItem = 3;

    public LRecyclerView(Context context) {
        this(context, null);
    }

    public LRecyclerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        addOnScrollListener(mOnScrollListener);
    }

    public void finishLoading() {
        mIsLoading = false;
    }

    public boolean isLoading() {
        return mIsLoading;
    }

    private OnScrollListener mOnScrollListener = new OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
           /* Log.i("liao", "newState=" + newState);

            //第一种方式  有个bug:当最后一个item刚显示出来的时候停止滑动这个时候也会触发滑动到底部的操作
            LayoutManager layoutManager = getLayoutManager();
            int itemCount = layoutManager.getItemCount();
            int lastVisibleItemPosition = 0;
            if (layoutManager instanceof LinearLayoutManager) {
                LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
                lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
                //得到这个数组后再取到数组中position值最大的那个就是最后显示的position值了
                int[] lastPositions = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
                staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
                lastVisibleItemPosition = findMax(lastPositions);
            }

            if (!mIsLoading && ((lastVisibleItemPosition + 1) >= itemCount) && newState == SCROLL_STATE_IDLE) {

                Log.i("liao", "加载.....lastVisibleItemPosition=" + lastVisibleItemPosition + ",itemCount=" + itemCount);
                mIsLoading = true;
                post(new Runnable() {
                    @Override
                    public void run() {
                        if (mOnLoadingListener != null) {
                            mOnLoadingListener.onLoading();
                        }
                    }
                });
            }*/

            //第二种方式
            //得到当前显示的最后一个item的view
            View lastChildView = recyclerView.getLayoutManager().getChildAt(recyclerView.getLayoutManager().getChildCount() - 1);
            //得到lastChildView的bottom坐标值
            int lastChildBottom = lastChildView.getBottom();
            //得到Recycler view的底部坐标减去底部padding值,也就是显示内容最底部的坐标
            int recyclerBottom = recyclerView.getBottom() - recyclerView.getPaddingBottom();
            //通过这个lastChildView得到这个view当前的position值
            int lastPosition = recyclerView.getLayoutManager().getPosition(lastChildView);

            //判断lastChildView的bottom值跟recyclerBottom
            //判断lastPosition是不是最后一个position
            //如果两个条件都满足则说明是真正的滑动到了底部
            if (!mIsLoading && lastChildBottom == recyclerBottom && lastPosition == recyclerView.getLayoutManager().getItemCount() - 1
                    && newState == SCROLL_STATE_IDLE) {
                mIsLoading = true;
                post(new Runnable() {
                    @Override
                    public void run() {
                        if (mOnLoadingListener != null) {
                            mOnLoadingListener.onLoading();
                        }
                    }
                });
            }
        }
    };

    //找到数组中的最大值
    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }

    private OnLoadingListener mOnLoadingListener;

    public void setOnLoadingListener(OnLoadingListener onLoadingListener) {
        mOnLoadingListener = onLoadingListener;
    }

    public interface OnLoadingListener {
        void onLoading();
    }
}

LoadingAdapter.java ----具有加载更多布局的adapter


/**
 * <p> </p>
 * Created by 行走的老者 on 2017/11/13 0013.
 */
public abstract class LoadingAdapter<B> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int FOOTER = 10000;
    private static final int NORMAL = 10001;

    public static final int STATUS_LOADING = 10;
    public static final int STATUS_LOADED = 11;
//    public static final int STATUS_LOADED = 11;

    @IntDef({STATUS_LOADING, STATUS_LOADED})
    public @interface Status {
    }

    private int mStatus = STATUS_LOADED;

    private List<B> mDataList;


    public void setDataList(List<B> dataList) {
        mDataList = dataList;
        notifyDataSetChanged();
    }

    public void setStatus(@Status int status) {
        mStatus = status;
        notifyDataSetChanged();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == FOOTER) {
            return new LoadingViewHolder(LayoutInflater.from(
                    parent.getContext()).inflate(R.layout.loading_more_layout, parent, false));
        } else
            return onCreateHolder(parent, viewType);
    }

    protected abstract RecyclerView.ViewHolder onCreateHolder(ViewGroup parent, int viewType);

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof LoadingViewHolder) return;
        onBindHolder(holder, position);
    }

    protected abstract void onBindHolder(RecyclerView.ViewHolder holder, int position);

    @Override
    public int getItemViewType(int position) {
        if (position == getItemCount() - 1 && mStatus == STATUS_LOADING) {
            return FOOTER;
        }
        return NORMAL;
    }

    @Override
    public int getItemCount() {
        return mDataList == null ? 0 : mDataList.size() + (mStatus == STATUS_LOADING ? 1 : 0);
    }

    //解决GridLayoutManager 占用问题
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return isFooter(position) ? gridManager.getSpanCount() : 1;
                }
            });
        }
    }

    private boolean isFooter(int position) {
        return mStatus == STATUS_LOADING && position == getItemCount();
    }

    //处理StaggeredGridLayoutManager 占用问题
    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        if (isStaggeredGridLayout(holder)) {
            handleLayoutIfStaggeredGridLayout(holder, holder.getLayoutPosition());
        }
    }

    private boolean isStaggeredGridLayout(RecyclerView.ViewHolder holder) {
        ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
        return layoutParams != null && layoutParams instanceof StaggeredGridLayoutManager.LayoutParams;
    }

    private void handleLayoutIfStaggeredGridLayout(RecyclerView.ViewHolder holder, int position) {
        if (/*isHeader(position) ||*/ isFooter(position)) {
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
            p.setFullSpan(true);
        }
    }

    public static class LoadingViewHolder extends RecyclerView.ViewHolder {

        public LoadingViewHolder(View itemView) {
            super(itemView);
        }
    }

    public static class NormalViewHolder extends RecyclerView.ViewHolder {

        public NormalViewHolder(View itemView) {
            super(itemView);
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容