public void moveView(int deltaY) { mHolder.move(deltaY); mHeaderView.offsetTopAndBottom(deltaY); mContentView.offsetTopAndBottom(deltaY); if (needAddFooterView()) { mFooterView.offsetTopAndBottom(deltaY); } invalidate(); if (mRefreshViewListener != null && (mContentView.isTop() || mPullRefreshing)) { double offset = 1.0 * mHolder.mOffsetY / mHeaderViewHeight; offset = offset > 1 ? 1 : offset; mRefreshViewListener.onHeaderMove(offset, mHolder.mOffsetY); mHeaderCallBack.onHeaderMove(offset, mHolder.mOffsetY); } }
public void startRefresh() { if (mHolder.mOffsetY != 0 || mContentView.isLoading() || !isEnabled()) { return; } // 如果条件成立,代表布局还没有初始化完成,改变标记,等待该方法再次调用,完成开始刷新 if (mHeaderCallBack == null) { this.autoRefresh = true; } else { mPullRefreshing = true; if (mRefreshViewListener != null) { mRefreshViewListener.onRefresh(); } mContentView.scrollToTop(); updateHeaderHeight(0, mHeaderViewHeight, 0); } }
private void startLoadMore() { mPullLoading = true; if (mRefreshViewListener != null) { mRefreshViewListener.onLoadMore(false); } }
@Override public boolean dispatchTouchEvent(MotionEvent ev) { final int action = ev.getAction(); int deltaY = 0; int deltaX = 0; switch (action) { case MotionEvent.ACTION_DOWN: mHasSendCancelEvent = false; mHasSendDownEvent = false; mLastY = (int) ev.getRawY(); mLastX = (int) ev.getRawX(); mInitialMotionY = mLastY; // if (!mScroller.isFinished() && !mPullRefreshing && !mPullLoading) // { // mScroller.forceFinished(true); // } break; case MotionEvent.ACTION_MOVE: mLastMoveEvent = ev; if (mPullLoading || mPullRefreshing || !isEnabled() || mIsIntercept || mHasScrollBack || mContentView.isLoading()) { if (mIsPinnedContentWhenRefreshing) { return super.dispatchTouchEvent(ev); } else { sendCancelEvent(); return true; } } int currentY = (int) ev.getRawY(); int currentX = (int) ev.getRawX(); deltaY = currentY - mLastY; deltaX = currentX - mLastX; mLastY = currentY; mLastX = currentX; // intercept the MotionEvent only when user is not scrolling if (!isIntercepted && (Math.abs(deltaY) < mTouchSlop)) { isIntercepted = true; return super.dispatchTouchEvent(ev); } if (isForHorizontalMove && !mMoveForHorizontal && Math.abs(deltaX) > mTouchSlop && Math.abs(deltaX) > Math.abs(deltaY)) { if (mHolder.mOffsetY == 0) { mMoveForHorizontal = true; } } if (mMoveForHorizontal) { return super.dispatchTouchEvent(ev); } LogUtils.d("isTop=" + mContentView.isTop() + ";isBottom=" + mContentView.isBottom()); if (deltaY > 0 && mHolder.mOffsetY <= mHeadMoveDistence || deltaY < 0) { deltaY = (int) (deltaY / OFFSET_RADIO); } else { deltaY = 0; } if (mContentView.isTop() && (deltaY > 0 || (deltaY < 0 && mHolder.hasHeaderPullDown()))) { sendCancelEvent(); updateHeaderHeight(currentY, deltaY); } else if (needAddFooterView() && mContentView.isBottom() && (deltaY < 0 || deltaY > 0 && mHolder.hasFooterPullUp())) { sendCancelEvent(); updateFooterHeight(deltaY); } else if (mContentView.isTop() && !mHolder.hasHeaderPullDown() || mContentView.isBottom() && !mHolder.hasFooterPullUp()) { if (Math.abs(deltaY) > 0) sendDownEvent(); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: // if (mHolder.mOffsetY != 0 && mRefreshViewListener != null // && !mPullRefreshing && !mPullLoading) { // mRefreshViewListener.onRelease(mHolder.mOffsetY); // } if (mHolder.hasHeaderPullDown() && !mHasScrollBack) { // invoke refresh if (mEnablePullRefresh && mHolder.mOffsetY > mHeaderViewHeight) { mPullRefreshing = true; mHeaderCallBack.onStateRefreshing(); mState = XRefreshViewState.STATE_REFRESHING; if (mRefreshViewListener != null) { mRefreshViewListener.onRefresh(); } } resetHeaderHeight(); } else if (mHolder.hasFooterPullUp()) { if (mEnablePullLoad && needAddFooterView() && !mHasLoadComplete) { invoketLoadMore(); } else { int offset = 0 - mHolder.mOffsetY; startScroll(offset, SCROLL_DURATION); } } mLastY = -1; // reset mInitialMotionY = 0; isIntercepted = true; mMoveForHorizontal = false; mIsIntercept = false; break; } return super.dispatchTouchEvent(ev); }