RecycleView下拉刷新控件的封装(包括下拉刷新和加载更多 )

最近学习了RecycleView控件的使用,就尝试封装了RecycleView 下拉刷新控件,实现的功能有(下拉刷新和加载更多)
转载请注明原博客地址:http://blog.csdn.net/gdutxiaoxu/article/details/51473358

1 思路解析

1)我是通过继承LinearLayout来实现的,里面拥有SwipeRefreshLayout和RecycleView
2)下拉刷新是通过SwipeRefreshLayout设置监听器实现的
mSwipeRfl.setOnRefreshListener(mRefreshListener);

3)加载更多是通过监听RecycleView的OnScrollListener

mScrollListener = new RecyclerView.OnScrollListener() {

    private int mLastVisibleItem;
    private int mDy;

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (newState != RecyclerView.SCROLL_STATE_IDLE) {
            return;
        }
        //最后显示的项
        mLastVisibleItem = mLayoutManager.findLastCompletelyVisibleItemPosition();
        int totalItemCount = mLayoutManager.getItemCount();
        /**
         * 只有在下拉,并且没有早加载更多,并且允许加载更多,并且在最后一个条目,才调用加载更多的接口
         */
        if (mDy >= 0 && !isLoadMore && (mLastVisibleItem >= totalItemCount - 1) &&
                enableLoadMore) {
            loadMore();
        }
    }

2 下面给出源码

public class PulltoRefreshRecyclerView extends LinearLayout {

    String Tag = "xujun";

    /**
     * 内容控件
     */
    private RecyclerView mRecyclerView;
    /**
     * 刷新布局控件
     */
    private SwipeRefreshLayout mSwipeRfl;
    private LinearLayoutManager mLayoutManager;
    /*
     * 刷新布局的监听
     */
    private OnRefreshListener mRefreshListener;
    /**
     * 内容控件滚动监听
     */
    private RecyclerView.OnScrollListener mScrollListener;

    /*
     * 刷新加载监听事件
     */
    private onRefreshListener mRefreshLoadMoreListner;

    /**
     * 是否正在刷新
     */
    private boolean isRefresh = false;
    /**
     * 是否正在加载更多
     */
    private boolean isLoadMore = false;
    private FrameLayout mFootView;
    //    是否允许加载更多
    private boolean enableLoadMore = true;
    private int mMeasuredHeight;

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

    @SuppressWarnings("deprecation")
    public PulltoRefreshRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 导入布局
        initView(context);


        /**
         * 监听上拉至底部滚动监听
         */
        initListener();
        mRecyclerView.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(context);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setOnScrollListener(mScrollListener);
    }

    private void setFootViewHeight(int height) {
        ViewGroup.LayoutParams layoutParams = mFootView.getLayoutParams();
        layoutParams.height = height;
        mFootView.setLayoutParams(layoutParams);
    }

    private void initListener() {
        mScrollListener = new RecyclerView.OnScrollListener() {

            private int mLastVisibleItem;
            private int mDy;

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState != RecyclerView.SCROLL_STATE_IDLE) {
                    return;
                }

                //最后显示的项
                mLastVisibleItem = mLayoutManager.findLastCompletelyVisibleItemPosition();

                int totalItemCount = mLayoutManager.getItemCount();

                /**
                 * 只有在下拉,并且没有早加载更多,并且允许加载更多,并且在最后一个条目,才调用加载更多的接口
                 */
                if (mDy >= 0 && !isLoadMore && (mLastVisibleItem >= totalItemCount - 1) &&
                        enableLoadMore) {
                    loadMore();


                }
            }

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

        };

        /**
         * 下拉至顶部刷新监听
         */
        mRefreshListener = new OnRefreshListener() {

            @Override
            public void onRefresh() {
            /*    Log.i("Tag", "onRefresh1");
                Log.i("Tag", isRefresh + "");
                Log.i("Tag", isRefresh + "");
                Log.i("Tag", isLoadMore + "");*/
                LUtils.i("isLoadMore=" + isLoadMore);
                if (!isRefresh && !isLoadMore) {//没有正在刷新或者正在加载更多
                    isRefresh = true;
                    refresh();
                }
            }
        };
        mSwipeRfl.setOnRefreshListener(mRefreshListener);
    }

    private void initView(Context context) {
        View.inflate(context, R.layout.pulltorefreshrecyclerview,this);
        mSwipeRfl = (SwipeRefreshLayout) findViewById(R.id.all_swipe);
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        initFootView();


    }

    private void initFootView() {
        mFootView = (FrameLayout) findViewById(R.id.ll_load_more);
        LUtils.i("mFootView=" +(mFootView==null));
        mFootView.measure(0, 0);
        mMeasuredHeight = mFootView.getMeasuredHeight();
        setFootViewHeight(0);

    }


    public void setFooterView(View view) {
        if (getFooterView() != null) {
            getFooterView().removeAllViews();
            mFootView.addView(view);
        }

    }

    public FrameLayout getFooterView() {
        return mFootView;
    }

    public RecyclerView getRecyclerView() {
        return mRecyclerView;
    }

    public void setLayoutManager(LayoutManager layoutManager) {
        if (mRecyclerView != null) {
            mRecyclerView.setLayoutManager(layoutManager);
        }
    }

    /**
     * 设置是否允许下拉刷新
     *
     * @param enable
     */
    public void setPullRefreshEnable(boolean enable) {
        setRefreshEnabled(enable);
    }

    public boolean getPullRefreshEnable() {
        return mSwipeRfl.isEnabled();
    }

    public void setLoadMoreListener() {
        mRecyclerView.setOnScrollListener(mScrollListener);
    }

    public void loadMore() {
        if (mRefreshLoadMoreListner != null) {
            isLoadMore = true;
            //设置在加载更多的时候swipeLayout不允许加载更多,同时需要设置在加载更多完毕的时候允许swipeLayout加载更多
            setRefreshEnabled(false);
            mLayoutManager.scrollToPosition(mLayoutManager.findLastVisibleItemPosition());
            showFootView();
            mRefreshLoadMoreListner.onLoadMore(mRecyclerView);

        }
    }

    public void setRefreshEnabled(boolean enabled) {
        mSwipeRfl.setEnabled(enabled);
    }

    private void showFootView() {
        setFootViewHeight(mMeasuredHeight);

    }

    public void OnRefreshCompleted() {
        if (isRefresh) {//如果是正在刷新,就调用这个方法
            stopRefresh();
        } else if (isLoadMore) {//如果是正在加载更多,就调用这个方法
            setLoadMoreCompleted();
        }


    }

    /**
     * 加载更多完毕,为防止频繁网络请求,isLoadMore为false才可再次请求更多数据
     */
    private void setLoadMoreCompleted() {

//因为在加载更多的时候设置swipeLayout不允刷新,
// 所以加载更多完毕的时候需要设置允许swipeLayout允许刷新
        setRefreshEnabled(true);
        isLoadMore = false;
        hideFootView();
    }

    private void hideFootView() {
//        setFootViewHeight(0);
        rollbackFootView(mFootView);
    }

    private void stopRefresh() {
        isRefresh = false;
        mSwipeRfl.setRefreshing(false);

    }

    public void setOnRefreshListener(onRefreshListener listener) {
        mRefreshLoadMoreListner = listener;
    }

    public void refresh() {
        if (mRefreshLoadMoreListner != null) {
            mRefreshLoadMoreListner.onRefresh(mRecyclerView);
        }
    }

    public void setAdapter(RecyclerView.Adapter adapter) {
        if (adapter != null)
            mRecyclerView.setAdapter(adapter);
    }

    public interface onRefreshListener {

        public void onRefresh(RecyclerView recyclerView);

        public void onLoadMore(RecyclerView recyclerView);
    }

    /**
     * 回滚下拉刷新头部控件
     */
    private void rollbackFootView(View view) {

        final ValueAnimator rbAnimator = ValueAnimator.ofInt(0, mMeasuredHeight);
        rbAnimator.setDuration(800);
        rbAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        rbAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float animatedFraction = animation.getAnimatedFraction();

                /**
                 * 当刷新完毕后,进行headerView的隐藏
                 */
                setFootViewHeight((int) (mMeasuredHeight - animatedFraction * mMeasuredHeight));
            }


        });
        rbAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                rbAnimator.removeAllListeners();
            }
        });
        rbAnimator.start();

    }

    public boolean isLoadMore() {
        return isLoadMore;
    }

    public boolean isRefresh() {
        return isRefresh;
    }

    public boolean isEnableLoadMore() {
        return enableLoadMore;
    }
}

3 存在的问题

1)在判断是够加载更多的时候 需要 mLastVisibleItem 
/**
 * 只有在下拉,并且没有早加载更多,并且允许加载更多,并且在最后一个条目,才调用加载更多的接口
 */
if (mDy >= 0 && !isLoadMore && (mLastVisibleItem >= totalItemCount - 1) &&
        enableLoadMore) {
    loadMore();
}
//最后显示的项
mLastVisibleItem = mLayoutManager.findLastCompletelyVisibleItemPosition();
但是findLastCompletelyVisibleItemPosition()这个方法是LinearLayoutManger里面的 方法 ,
LinearLayoutManger的父类里面 RecyclerView.LayoutManager
没有这个方法findLastCompletelyVisibleItemPosition();
这样导致我们 无法动态更改我们当前RecycleView实例的 LayoutManger

2)暂时没有实现SwipeLayoutProgress下拉刷新显示进度条 离我们第一个item之间的距离,可以参考
3)暂时没有实现自定义属性,使用起来没有那么方便
4)源码下载地址https://github.com/gdutxiaoxu/RecycleViewDemo




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gdutxiaoxu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值