예제 #1
0
  /** Re-measure the Loading Views height, and adjust internal padding as necessary */
  protected final void refreshLoadingViewsSize() {
    final int maximumPullScroll = (int) (getMaximumPullScroll() * 1.2f);

    int pLeft = getPaddingLeft();
    int pTop = getPaddingTop();
    int pRight = getPaddingRight();
    int pBottom = getPaddingBottom();

    switch (getPullToRefreshScrollDirection()) {
      case HORIZONTAL:
        if (mMode.showHeaderLoadingLayout()) {
          mHeaderLayout.setWidth(maximumPullScroll);
          pLeft = -maximumPullScroll;
        } else {
          pLeft = 0;
        }

        if (mMode.showFooterLoadingLayout()) {
          mFooterLayout.setWidth(maximumPullScroll);
          pRight = -maximumPullScroll;
        } else {
          pRight = 0;
        }
        break;

      case VERTICAL:
        if (mMode.showHeaderLoadingLayout()) {
          mHeaderLayout.setHeight(maximumPullScroll);
          pTop = -maximumPullScroll;
        } else {
          pTop = 0;
        }

        if (mMode.showFooterLoadingLayout()) {
          mFooterLayout.setHeight(maximumPullScroll);
          pBottom = -maximumPullScroll;
        } else {
          pBottom = 0;
        }
        break;
    }

    if (DEBUG) {
      Log.d(
          LOG_TAG,
          String.format(
              "Setting Padding. L: %d, T: %d, R: %d, B: %d", pLeft, pTop, pRight, pBottom));
    }
    setPadding(pLeft, pTop, pRight, pBottom);
  }
예제 #2
0
  /**
   * 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() {
    // We need to use the correct LayoutParam values, based on scroll
    // direction
    final LayoutParams lp = getLoadingLayoutLayoutParams();

    // Remove Header, and then add Header Loading View again if needed
    if (this == mHeaderLayout.getParent()) {
      removeView(mHeaderLayout);
    }
    if (mMode.showHeaderLoadingLayout()) {
      addViewInternal(mHeaderLayout, 0, lp);
    }

    // Remove Footer, and then add Footer Loading View again if needed
    if (this == mFooterLayout.getParent()) {
      removeView(mFooterLayout);
    }
    if (mMode.showFooterLoadingLayout()) {
      addViewInternal(mFooterLayout, lp);
    }

    // Hide Loading Views
    refreshLoadingViewsSize();

    // If we're not using Mode.BOTH, set mCurrentMode to mMode, otherwise
    // set it to pull down
    mCurrentMode = (mMode != Mode.BOTH) ? mMode : Mode.PULL_FROM_START;
  }
예제 #3
0
  @Override
  public final boolean demo() {
    if (mMode.showHeaderLoadingLayout() && isReadyForPullStart()) {
      smoothScrollToAndBack(-getHeaderSize() * 2);
      return true;
    } else if (mMode.showFooterLoadingLayout() && isReadyForPullEnd()) {
      smoothScrollToAndBack(getFooterSize() * 2);
      return true;
    }

    return false;
  }
예제 #4
0
  /**
   * Used internally for {@link #getLoadingLayoutProxy(boolean, boolean)}. Allows derivative classes
   * to include any extra LoadingLayouts.
   */
  protected LoadingLayoutProxy createLoadingLayoutProxy(
      final boolean includeStart, final boolean includeEnd) {
    LoadingLayoutProxy proxy = new LoadingLayoutProxy();

    if (includeStart && mMode.showHeaderLoadingLayout()) {
      proxy.addLayout(mHeaderLayout);
    }
    if (includeEnd && mMode.showFooterLoadingLayout()) {
      proxy.addLayout(mFooterLayout);
    }

    return proxy;
  }
  private void addIndicatorViews() {
    Mode mode = getMode();
    FrameLayout refreshableViewWrapper = getRefreshableViewWrapper();

    if (mode.showHeaderLoadingLayout() && null == mIndicatorIvTop) {
      // If the mode can pull down, and we don't have one set already
      mIndicatorIvTop = new IndicatorLayout(getContext(), Mode.PULL_FROM_START);
      FrameLayout.LayoutParams params =
          new FrameLayout.LayoutParams(
              ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
      params.rightMargin =
          getResources().getDimensionPixelSize(com.android.common.R.dimen.indicator_right_padding);
      params.gravity = Gravity.TOP | Gravity.RIGHT;
      refreshableViewWrapper.addView(mIndicatorIvTop, params);

    } else if (!mode.showHeaderLoadingLayout() && null != mIndicatorIvTop) {
      // If we can't pull down, but have a View then remove it
      refreshableViewWrapper.removeView(mIndicatorIvTop);
      mIndicatorIvTop = null;
    }

    if (mode.showFooterLoadingLayout() && null == mIndicatorIvBottom) {
      // If the mode can pull down, and we don't have one set already
      mIndicatorIvBottom = new IndicatorLayout(getContext(), Mode.PULL_FROM_END);
      FrameLayout.LayoutParams params =
          new FrameLayout.LayoutParams(
              ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
      params.rightMargin =
          getResources().getDimensionPixelSize(com.android.common.R.dimen.indicator_right_padding);
      params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
      refreshableViewWrapper.addView(mIndicatorIvBottom, params);

    } else if (!mode.showFooterLoadingLayout() && null != mIndicatorIvBottom) {
      // If we can't pull down, but have a View then remove it
      refreshableViewWrapper.removeView(mIndicatorIvBottom);
      mIndicatorIvBottom = null;
    }
  }
  @Override
  protected LoadingLayoutProxy createLoadingLayoutProxy(
      final boolean includeStart, final boolean includeEnd) {
    LoadingLayoutProxy proxy = super.createLoadingLayoutProxy(includeStart, includeEnd);

    if (mListViewExtrasEnabled) {
      final Mode mode = getMode();

      if (includeStart && mode.showHeaderLoadingLayout()) {
        proxy.addLayout(mHeaderLoadingView);
      }
      if (includeEnd && mode.showFooterLoadingLayout()) {
        proxy.addLayout(mFooterLoadingView);
      }
    }

    return proxy;
  }
예제 #7
0
  /**
   * Called when the UI has been to be updated to be in the {@link
   * com.handmark.pulltorefresh.library.PullToRefreshBase.State#REFRESHING} or {@link
   * com.handmark.pulltorefresh.library.PullToRefreshBase.State#MANUAL_REFRESHING} state.
   *
   * @param doScroll - Whether the UI should scroll for this event.
   */
  protected void onRefreshing(final boolean doScroll) {
    if (mMode.showHeaderLoadingLayout()) {
      mHeaderLayout.refreshing();
    }
    if (mMode.showFooterLoadingLayout()) {
      mFooterLayout.refreshing();
    }

    if (doScroll) {
      if (mShowViewWhileRefreshing) {

        // Call Refresh Listener when the Scroll has finished
        OnSmoothScrollFinishedListener listener =
            new OnSmoothScrollFinishedListener() {
              @Override
              public void onSmoothScrollFinished() {
                callRefreshListener();
              }
            };

        switch (mCurrentMode) {
          case MANUAL_REFRESH_ONLY:
          case PULL_FROM_END:
            smoothScrollTo(getFooterSize(), listener);
            break;
          default:
          case PULL_FROM_START:
            smoothScrollTo(-getHeaderSize(), listener);
            break;
        }
      } else {
        smoothScrollTo(0);
      }
    } else {
      // We're not scrolling, so just call Refresh Listener now
      callRefreshListener();
    }
  }
예제 #8
0
 /**
  * @deprecated You should now call this method on the result of {@link
  *     #getLoadingLayoutProxy(boolean, boolean)}.
  */
 public void setReleaseLabel(CharSequence releaseLabel, Mode mode) {
   getLoadingLayoutProxy(mode.showHeaderLoadingLayout(), mode.showFooterLoadingLayout())
       .setReleaseLabel(releaseLabel);
 }
예제 #9
0
 /**
  * @deprecated You should now call this method on the result of {@link
  *     #getLoadingLayoutProxy(boolean, boolean)}.
  */
 public void setPullLabel(CharSequence pullLabel, Mode mode) {
   getLoadingLayoutProxy(mode.showHeaderLoadingLayout(), mode.showFooterLoadingLayout())
       .setPullLabel(pullLabel);
 }
예제 #10
0
 /**
  * @deprecated You should now call this method on the result of {@link
  *     #getLoadingLayoutProxy(boolean, boolean)}.
  */
 public void setLoadingDrawable(Drawable drawable, Mode mode) {
   getLoadingLayoutProxy(mode.showHeaderLoadingLayout(), mode.showFooterLoadingLayout())
       .setLoadingDrawable(drawable);
 }
예제 #11
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 (!mScrollingWhileRefreshingEnabled && isRefreshing()) {
            return true;
          }

          if (isReadyForPull()) {
            final float y = event.getY(), x = event.getX();
            final float diff, oppositeDiff, absDiff;

            // We need to use the correct values, based on scroll
            // direction
            switch (getPullToRefreshScrollDirection()) {
              case HORIZONTAL:
                diff = x - mLastMotionX;
                oppositeDiff = y - mLastMotionY;
                break;
              case VERTICAL:
              default:
                diff = y - mLastMotionY;
                oppositeDiff = x - mLastMotionX;
                break;
            }
            absDiff = Math.abs(diff);

            if (absDiff > mTouchSlop && (!mFilterTouchEvents || absDiff > Math.abs(oppositeDiff))) {
              if (mMode.showHeaderLoadingLayout() && diff >= 1f && isReadyForPullStart()) {
                mLastMotionY = y;
                mLastMotionX = x;
                mIsBeingDragged = true;
                if (mMode == Mode.BOTH) {
                  mCurrentMode = Mode.PULL_FROM_START;
                }
              } else if (mMode.showFooterLoadingLayout() && diff <= -1f && isReadyForPullEnd()) {
                mLastMotionY = y;
                mLastMotionX = x;
                mIsBeingDragged = true;
                if (mMode == Mode.BOTH) {
                  mCurrentMode = Mode.PULL_FROM_END;
                }
              }
            }
          }
          break;
        }
      case MotionEvent.ACTION_DOWN:
        {
          if (isReadyForPull()) {
            mLastMotionY = mInitialMotionY = event.getY();
            mLastMotionX = mInitialMotionX = event.getX();
            mIsBeingDragged = false;
          }
          break;
        }
    }

    return mIsBeingDragged;
  }