SwipeRefreshLoadLayout + RecyclerView 实现下列刷新,上拉加载

使用过 SwipeRefreshLayout 的都知道,这个控件谷歌只添加下拉刷新,如果需要上拉加载,就需要自己去实现,这里是结合RecyclerView添加了上拉加载功能,列出代码仅供参考。

这里是SwipeRefreshLoadLayout源码:

/**
 * @author ttarfall
 * @date 2016-03-25 12:32
 */
public class SwipeRefreshLoadLayout extends SwipeRefreshLayout {
    private static final String TAG = "SwipeRefreshLoadLayout";

    /**
     * 滑动到最下面时的上拉操作 有效距离
     */
    private int mTouchSlop;
    private RecyclerView recyclerView;
    /**
     * 刷新回调接口
     */
    private OnRefreshListener mListener;
    /**
     * 上拉加载回调接口
     */
    private OnLoadListener onLoadListener;
    private float downY, lastY;
    /**
     * 是否在加载中 ( 上拉加载更多 )
     */
    private boolean isLoading = false;
    /**
     * 设置是否支持自动加载 默认不支持
     */
    private boolean mIsAutoLoad = false;
    /**
     * 支持自动上拉加载触发的有效行数
     */
    private int autoLoadCount = 1;
    /**
     * 自动刷新线程
     */
    private Runnable autoRefreshRunnable;
    /**
     * 加载数据线程
     */
    private Runnable loadDataRunnable;

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

    public SwipeRefreshLoadLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        getView();
        setColorSchemeColors(getResources().getColor(R.color.bg_orange_red));
    }

    /**
     * 设置加载状态
     *
     * @param isLoading
     */
    public void setIsLoading(boolean isLoading) {
        this.isLoading = isLoading;
    }

    /**
     * 是否正在加载中
     *
     * @return
     */
    public boolean isLoading() {
        return isLoading;
    }

    /**
     * 设置是否自动上拉加载
     *
     * @param isAutoLoad
     */
    public void setAutoLoad(boolean isAutoLoad) {
        mIsAutoLoad = isAutoLoad;
    }

    @Override
    public void setOnRefreshListener(OnRefreshListener listener) {
        super.setOnRefreshListener(listener);
        mListener = listener;
    }

    /**
     * 默认等待时间
     */
    private static final long DEFAULT_DELAYMILLIS = 300;

    /**
     * 自动下拉刷新
     */
    public void setAutoRefreshing() {
        setAutoRefreshing(DEFAULT_DELAYMILLIS);
    }

    /**
     * 启动自动刷新
     *
     * @param delayMillis
     */

    private void setAutoRefreshing(final long delayMillis) {
        if (autoRefreshRunnable == null && !isRefreshing() && !isLoading) {//启动自动刷新,前提是界面不处于刷新中和加载中
            autoRefreshRunnable = new Runnable() {
                @Override
                public void run() {
                    int height = getHeight();
                    if (height > 0) {//只有视图创建以后,高度才会大于0,因此在视图创建以后再发起自动刷新
                        if (mListener != null) {
                            setRefreshing(true);
                            mListener.onRefresh();
                        }
                    } else {
                        setAutoRefreshing(delayMillis);
                    }
                }
            };

        }
        handler.postDelayed(autoRefreshRunnable, delayMillis);
    }

    public void setRefreshing(boolean refreshing) {
        if (isLoading) {
            super.setRefreshing(false);
        } else {
            super.setRefreshing(refreshing);
            getView();
            if (recyclerView != null) {
                RecyclerView.Adapter a = recyclerView.getAdapter();
                if (a instanceof BaseLoadAdapter) {
                    ((BaseLoadAdapter) a).setLoading(false);
                }
            }
        }
    }

    private void getView() {
        //当RecyclerView视图为空,并且使用了上拉加载监听回调才获取视图
        if (recyclerView == null && onLoadListener != null) {
            getView(this);
        }
    }

    private void getView(View viewParent) {
        if (viewParent instanceof ViewGroup) {
            int count = ((ViewGroup) viewParent).getChildCount();
            for (int i = 0; i < count; i++) {
                View view = ((ViewGroup) viewParent).getChildAt(i);
                if (view instanceof RecyclerView) {
                    recyclerView = (RecyclerView) view;
                    RecyclerView.Adapter a = recyclerView.getAdapter();
                    if (a instanceof BaseLoadAdapter)
                        ((BaseLoadAdapter) a).setSwipeRefreshLoadLayout(this);
                    break;
                } else {
                    getView(view);
                }
            }
        }
    }

    public void setOnLoadListener(OnLoadListener onLoadListener) {
        this.onLoadListener = onLoadListener;
    }

    public OnLoadListener getOnLoadListener() {
        return onLoadListener;
    }

    /**
     * 判断是否到了最底部
     */
    private boolean isBottom() {
        getView();
        if (recyclerView != null) {
            RecyclerView.Adapter a = recyclerView.getAdapter();
            RecyclerView.LayoutManager m = recyclerView.getLayoutManager();
            if (m instanceof LinearLayoutManager) {
                LinearLayoutManager lm = (LinearLayoutManager) m;
                if (mIsAutoLoad) {
                    return lm.findLastCompletelyVisibleItemPosition() > a.getItemCount() - autoLoadCount;
                } else {
                    return lm.findLastCompletelyVisibleItemPosition() == a.getItemCount() - 1;
                }
            }
        }


        return false;
    }

    /**
     * 设置触发自动上拉加载的有效行数
     *
     * @param count
     */
    public void setAutoLoadCount(int count) {
        if (count < 1) {
            return;
        }
        if (!mIsAutoLoad) {
            mIsAutoLoad = !mIsAutoLoad;
        }
        autoLoadCount = count;
    }

    public int getAutoLoadCount() {
        return autoLoadCount;
    }

    /**
     * 是否是上拉操作
     *
     * @return
     */
    private boolean isPullUp() {
        return (downY - lastY) >= mTouchSlop;
    }

    /**
     * 是否可以加载更多, 条件是到了最底部, View不在加载中, 且为上拉操作, 并且不是下拉刷新
     *
     * @return
     */
    private boolean canLoad() {
        return isBottom() && !isLoading && isPullUp() && !isRefreshing();
    }

    private int msgCount = 0;
    private boolean isCountineMove = false;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MotionEvent.ACTION_MOVE:
                    if (msgCount == 1) {
                        if (!isLoading && onLoadListener != null) {//当正在load不在进入执行
                            if (isPullUp()) {
                                getView();
                                if (recyclerView != null) {
                                    RecyclerView.Adapter a = recyclerView.getAdapter();
                                    if (a instanceof BaseLoadAdapter) {
                                        ((BaseLoadAdapter) a).setLoadBefore();
                                    }
                                }
                            }
                        }
                        msgCount = 0;
                    } else {
                        if (msgCount > 0) {
                            msgCount--;
                        } else {
                            msgCount = 0;
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    if (!isCountineMove) {
                        if (!isLoading && onLoadListener != null) {//当正在load不在进入执行
                            if (canLoad()) {
                                msgCount = 0;//如果开始加重下一页,msgCount为0
                                loadData();
                            }
                        }
                    }
                    break;
                default:
                    break;
            }
            super.handleMessage(msg);
        }
    };

    private long historyTime = 0;

    /**
     * 是否可以发送消息
     *
     * @return
     */
    private boolean isSendMessage() {
        long curTime = System.currentTimeMillis();
        if (curTime - historyTime > 500) {
            historyTime = curTime;
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!isLoading && onLoadListener != null) {//当正在load不在进入执行
                    downY = ev.getY();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isLoading && onLoadListener != null && isSendMessage()) {
                    isCountineMove = true;
                    msgCount++;
                    LogUtil.i("action=" + MotionEvent.ACTION_MOVE + ", msgCount=" + msgCount);
                    lastY = ev.getY();
                    Message msg = new Message();
                    msg.what = MotionEvent.ACTION_MOVE;
                    handler.sendMessageDelayed(msg, 500);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (!isLoading && onLoadListener != null) {
                    isCountineMove = false;
                    LogUtil.i("action=" + MotionEvent.ACTION_MOVE + ", msgCount=" + msgCount);
                    lastY = ev.getY();
                    Message msg = new Message();
                    msg.what = MotionEvent.ACTION_UP;
                    handler.sendMessageDelayed(msg, 500);
                }
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * @param loading
     */
    public void setLoading(boolean loading) {
        isLoading = loading;
        if (!isLoading) {
            downY = 0;
            lastY = 0;
        }
        getView();
        if (recyclerView != null) {
            RecyclerView.Adapter a = recyclerView.getAdapter();
            if (a instanceof BaseLoadAdapter) {
                ((BaseLoadAdapter) a).setLoading(loading);
            }
        }
    }

    /**
     * 如果到了最底部,而且是上拉操作.那么执行onLoad方法
     */
    private void loadData() {
        DebugUtil.i(TAG, "loadData 方法执行");
        if (onLoadListener != null) {
            // 设置状态
            setLoading(true);
            if (loadDataRunnable == null)
                loadDataRunnable = new Runnable() {
                    @Override
                    public void run() {
                        onLoadListener.onLoad();
                    }
                };
            handler.postDelayed(loadDataRunnable, 500);
        } else {
            setLoading(false);
        }
    }

    /**
     * 加载更多的监听器
     *
     * @author mrsimple
     */
    public interface OnLoadListener {
        public void onLoad();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值