private void addIndicatorViews() { final Mode mode = getMode(); if (mode.canPullDown() && null == mIndicatorIvTop) { // If the mode can pull down, and we don't have one set already mIndicatorIvTop = new IndicatorLayout(getContext(), Mode.PULL_DOWN_TO_REFRESH); final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.rightMargin = getResources().getDimensionPixelSize(R.dimen.indicator_right_padding); params.gravity = Gravity.TOP | Gravity.RIGHT; mRefreshableViewHolder.addView(mIndicatorIvTop, params); } else if (!mode.canPullDown() && null != mIndicatorIvTop) { // If we can't pull down, but have a View then remove it mRefreshableViewHolder.removeView(mIndicatorIvTop); mIndicatorIvTop = null; } if (mode.canPullUp() && null == mIndicatorIvBottom) { // If the mode can pull down, and we don't have one set already mIndicatorIvBottom = new IndicatorLayout(getContext(), Mode.PULL_UP_TO_REFRESH); final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.rightMargin = getResources().getDimensionPixelSize(R.dimen.indicator_right_padding); params.gravity = Gravity.BOTTOM | Gravity.RIGHT; mRefreshableViewHolder.addView(mIndicatorIvBottom, params); } else if (!mode.canPullUp() && null != mIndicatorIvBottom) { // If we can't pull down, but have a View then remove it mRefreshableViewHolder.removeView(mIndicatorIvBottom); mIndicatorIvBottom = null; } }
/** Re-measure the Loading Views height, and adjust internal padding as necessary */ private void refreshLoadingViewsHeight() { if (mMode.canPullDown()) { measureView(mHeaderLayout); mHeaderHeight = mHeaderLayout.getMeasuredHeight(); } else if (mMode.canPullUp()) { measureView(mFooterLayout); mHeaderHeight = mFooterLayout.getMeasuredHeight(); } else { mHeaderHeight = 0; } // Hide Loading Views switch (mMode) { case DISABLED: setPadding(0, 0, 0, 0); case BOTH: setPadding(0, -mHeaderHeight, 0, -mHeaderHeight); break; case PULL_UP_TO_REFRESH: setPadding(0, 0, 0, -mHeaderHeight); break; case PULL_DOWN_TO_REFRESH: default: setPadding(0, -mHeaderHeight, 0, 0); break; } }
/** * Updates the View State when the mode has been set. This does not do any checking that the mode * is different to current state so always updates. */ protected void updateUIForMode() { // Remove Header, and then add Header Loading View again if needed if (this == mHeaderLayout.getParent()) { removeView(mHeaderLayout); } if (mMode.canPullDown()) { LinearLayout.LayoutParams llp = new LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); llp.setMargins(mMargin, 0, mMargin, 0); addViewInternal(mHeaderLayout, 0, llp); } // Remove Footer, and then add Footer Loading View again if needed if (this == mFooterLayout.getParent()) { removeView(mFooterLayout); } if (mMode.canPullUp()) { LinearLayout.LayoutParams llp = new LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); llp.setMargins(mMargin, 0, mMargin, 0); addViewInternal(mFooterLayout, 0, llp); } // Hide Loading Views refreshLoadingViewsHeight(); // If we're not using Mode.BOTH, set mCurrentMode to mMode, otherwise // set it to pull down mCurrentMode = (mMode != Mode.BOTH) ? mMode : Mode.PULL_DOWN_TO_REFRESH; }
/** * Set Text to show when the Widget is being pulled, and will refresh when released * * @param releaseLabel - String to display * @param mode - Controls which Header/Footer Views will be updated. <code>Mode.BOTH</code> will * update all available, other values will update the relevant View. */ public void setReleaseLabel(String releaseLabel, Mode mode) { if (null != mHeaderLayout && mode.canPullDown()) { mHeaderLayout.setReleaseLabel(releaseLabel); } if (null != mFooterLayout && mode.canPullUp()) { mFooterLayout.setReleaseLabel(releaseLabel); } }
@Override public void setRefreshingLabel(String refreshingLabel, Mode mode) { if (null != mHeaderLayout && mode.canPullDown()) { mHeaderLayout.setRefreshingLabel(refreshingLabel); } if (null != mFooterLayout && mode.canPullUp()) { mFooterLayout.setRefreshingLabel(refreshingLabel); } }
public void setReleaseLabel(String releaseLabel, Mode mode) { super.setReleaseLabel(releaseLabel, mode); if (null != mHeaderLoadingView && mode.canPullDown()) { mHeaderLoadingView.setReleaseLabel(releaseLabel); } if (null != mFooterLoadingView && mode.canPullUp()) { mFooterLoadingView.setReleaseLabel(releaseLabel); } }
/** * Set the drawable used in the loading layout. * * @param drawable - Drawable to display * @param mode - Controls which Header/Footer Views will be updated. <code>Mode.BOTH</code> will * update all available, other values will update the relevant View. */ public void setLoadingDrawable(Drawable drawable, Mode mode) { if (null != mHeaderLayout && mode.canPullDown()) { mHeaderLayout.setLoadingDrawable(drawable); } if (null != mFooterLayout && mode.canPullUp()) { mFooterLayout.setLoadingDrawable(drawable); } // The Loading Height may have changed, so refresh refreshLoadingViewsHeight(); }
protected void resetHeader() { mState = PULL_TO_REFRESH; mIsBeingDragged = false; if (mMode.canPullDown()) { mHeaderLayout.reset(); } if (mMode.canPullUp()) { mFooterLayout.reset(); } smoothScrollTo(0); }
protected void setRefreshingInternal(boolean doScroll) { mState = REFRESHING; if (mMode.canPullDown()) { mHeaderLayout.refreshing(); } if (mMode.canPullUp()) { mFooterLayout.refreshing(); } if (doScroll) { if (mShowViewWhileRefreshing) { smoothScrollTo(mCurrentMode == Mode.PULL_DOWN_TO_REFRESH ? -mHeaderHeight : mHeaderHeight); } else { smoothScrollTo(0); } } }
@Override public final boolean onInterceptTouchEvent(MotionEvent event) { if (!isPullToRefreshEnabled()) { return false; } final int action = event.getAction(); if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { mIsBeingDragged = false; return false; } if (action != MotionEvent.ACTION_DOWN && mIsBeingDragged) { return true; } switch (action) { case MotionEvent.ACTION_MOVE: { // If we're refreshing, and the flag is set. Eat all MOVE events if (mDisableScrollingWhileRefreshing && isRefreshing()) { return true; } if (isReadyForPull()) { final float y = event.getY(); final float dy = y - mLastMotionY; final float yDiff = Math.abs(dy); final float xDiff = Math.abs(event.getX() - mLastMotionX); if (yDiff > mTouchSlop && (!mFilterTouchEvents || yDiff > xDiff)) { if (mMode.canPullDown() && dy >= 1f && isReadyForPullDown()) { mLastMotionY = y; mIsBeingDragged = true; if (mMode == Mode.BOTH) { mCurrentMode = Mode.PULL_DOWN_TO_REFRESH; } } else if (mMode.canPullUp() && dy <= -1f && isReadyForPullUp()) { mLastMotionY = y; mIsBeingDragged = true; if (mMode == Mode.BOTH) { mCurrentMode = Mode.PULL_UP_TO_REFRESH; } } } } break; } case MotionEvent.ACTION_DOWN: { if (isReadyForPull()) { mLastMotionY = mInitialMotionY = event.getY(); mLastMotionX = event.getX(); mIsBeingDragged = false; } break; } } return mIsBeingDragged; }