Dev-Wiki
4/22/2017 - 8:06 AM

滚动回调的RecyclerView

滚动回调的RecyclerView

public class TouchRecyclerView extends RecyclerView {

    private static final String TAG = "TouchRecyclerView";

    private OnScrollCallback mScrollCallback;
    private boolean isMoved = false;
    private boolean isScrolled = false;
    private int draggingCount = 0;

    public TouchRecyclerView(Context context) {
        super(context);
        init();
    }

    public TouchRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public TouchRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        OnScrollListener scrollListener = new OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                DevLog.d("newState:" + newState);
                if (newState == RecyclerView.SCROLL_STATE_SETTLING) {
                    //自己在滚动
                } else if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                    //随手指滚动
                    draggingCount = draggingCount + 1;
                } else {
                    //停止滚动
                    if (isScrolled && mScrollCallback != null) {
                        mScrollCallback.onScrollIdle();
                    }
                    if (isScrolled && !canScrollVertically(1)) {
                        mScrollCallback.onScrollToBottom();
                    }
                    if (isScrolled && !canScrollVertically(-1)) {
                        mScrollCallback.onScrollToTop();
                    }
                    isScrolled = false;
                    isMoved = false;
                    draggingCount = 0;
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                DevLog.d("state:" + recyclerView.getScrollState());
                DevLog.d("dy:" + dy);
                isScrolled = (dy != 0);
                if (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_SETTLING) {
                    if (dy > 0) {
                        if (mScrollCallback != null) {
                            mScrollCallback.onSettlingScrollDown();
                        }
                    } else {
                        if (mScrollCallback != null) {
                            mScrollCallback.onSettlingScrollUp();
                        }
                    }
                } else if (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
                    if (dy > 0) {
                        if (mScrollCallback != null) {
                            mScrollCallback.onDraggingScrollDown();
                        }
                    } else {
                        if (mScrollCallback != null) {
                            mScrollCallback.onDraggingScrollUp();
                        }
                    }
                }
                super.onScrolled(recyclerView, dx, dy);
            }
        };
        addOnScrollListener(scrollListener);
    }

    public void setScrollCallback(@NonNull OnScrollCallback scrollCallback) {
        mScrollCallback = scrollCallback;
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        DevLog.d("action:" + e.getAction());
        if (e.getAction() == MotionEvent.ACTION_MOVE) {
            isMoved = true;
        }
        if (e.getAction() == MotionEvent.ACTION_UP) {
            if (isMoved && draggingCount == 1) {
                if (!canScrollVertically(1)) {
                    mScrollCallback.onBottomDraggingUp();
                }
                if (!canScrollVertically(-1)) {
                    mScrollCallback.onTopDraggingDown();
                }
            }
        }
        return super.onTouchEvent(e);
    }

    interface OnScrollCallback {

        /**
         * 自己往列表顶部方向滚动
         */
        void onSettlingScrollUp();

        /**
         * 自己往列表底部方向滚动
         */
        void onSettlingScrollDown();

        /**
         * 列表停止滚动
         */
        void onScrollIdle();

        /**
         * 滚动到列表底部
         */
        void onScrollToBottom();

        /**
         * 滚动到列表顶部
         */
        void onScrollToTop();

        /**
         * 向列表顶部方向拖动滚动
         */
        void onDraggingScrollUp();

        /**
         * 向列表底部方向拖动滚动
         */
        void onDraggingScrollDown();

        /**
         * 在列表顶部往下拖拽
         */
        void onTopDraggingDown();

        /**
         * 在列表底部往上拖拽
         */
        void onBottomDraggingUp();
    }
}