/**
   * Create a {@code LoadingLayout} instance matched by <b>{@code clazz} token</b>
   *
   * @param layoutCode Loading layout code, which must be defined in pulltorefresh.xml
   * @param context
   * @param mode
   * @return {@code LoadingLayout} instance if the class matched by {@code layoutCode} exists, or
   *     {@code RotateLoadingLayout} instance if not
   */
  public static LoadingLayout createLoadingLayout(
      Class<? extends LoadingLayout> clazz,
      Context context,
      Mode mode,
      Orientation orientation,
      TypedArray attrs) {
    LoadingLayout layout = null;
    // Prevent NullPointerException
    if (clazz == null) {
      Log.i(
          LOG_TAG,
          "The Class token of the Loading Layout is missing. Default Loading Layout will be used.");
      clazz = DefaultLoadingLayoutFactory.createLoadingLayoutClazz("");
    }

    layout = tryNewInstance(clazz, context, mode, orientation, attrs);

    // If trying to create new instance has failed,
    if (layout == null) {
      layout =
          DefaultLoadingLayoutFactory.createLoadingLayout(clazz, context, mode, orientation, attrs);
    }

    layout.setVisibility(View.INVISIBLE);
    return layout;
  }
  @Override
  protected void handleStyledAttributes(TypedArray a) {
    super.handleStyledAttributes(a);

    mListViewExtrasEnabled = a.getBoolean(R.styleable.PullToRefresh_ptrListViewExtrasEnabled, true);

    if (mListViewExtrasEnabled) {
      final FrameLayout.LayoutParams lp =
          new FrameLayout.LayoutParams(
              FrameLayout.LayoutParams.MATCH_PARENT,
              FrameLayout.LayoutParams.WRAP_CONTENT,
              Gravity.CENTER_HORIZONTAL);

      // Create Loading Views ready for use later
      FrameLayout frame = new FrameLayout(getContext());
      mHeaderLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_START, a);
      mHeaderLoadingView.setVisibility(View.GONE);
      frame.addView(mHeaderLoadingView, lp);
      mRefreshableView.addHeaderView(frame, null, false);

      mLvFooterLoadingFrame = new FrameLayout(getContext());
      mFooterLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_END, a);
      mFooterLoadingView.setVisibility(View.GONE);
      mLvFooterLoadingFrame.addView(mFooterLoadingView, lp);

      /**
       * If the value for Scrolling While Refreshing hasn't been explicitly set via XML, enable
       * Scrolling While Refreshing.
       */
      if (!a.hasValue(R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) {
        setScrollingWhileRefreshingEnabled(true);
      }
    }
  }
 protected LoadingLayout createLoadingLayout(Context context, Mode mode, TypedArray attrs) {
   LoadingLayout layout =
       mLoadingAnimationStyle.createLoadingLayout(
           context, mode, getPullToRefreshScrollDirection(), attrs);
   layout.setVisibility(View.INVISIBLE);
   return layout;
 }
  /**
   * 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;
  }
  /**
   * 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;
  }
  /** 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;
    }
  }
 /**
  * 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 setPullLabel(String pullLabel) {
    super.setPullLabel(pullLabel);

    if (null != mHeaderLoadingView) {
      mHeaderLoadingView.setPullLabel(pullLabel);
    }
    if (null != mFooterLoadingView) {
      mFooterLoadingView.setPullLabel(pullLabel);
    }
  }
  public void setRefreshingLabel(String refreshingLabel) {
    super.setRefreshingLabel(refreshingLabel);

    if (null != mHeaderLoadingView) {
      mHeaderLoadingView.setRefreshingLabel(refreshingLabel);
    }
    if (null != mFooterLoadingView) {
      mFooterLoadingView.setRefreshingLabel(refreshingLabel);
    }
  }
 /** Called when the UI needs to be updated to the 'Release to Refresh' state */
 protected void onReleaseToRefresh() {
   switch (mCurrentMode) {
     case PULL_UP_TO_REFRESH:
       mFooterLayout.releaseToRefresh();
       break;
     case PULL_DOWN_TO_REFRESH:
       mHeaderLayout.releaseToRefresh();
       break;
   }
 }
  /**
   * Called when the UI has been to be updated to be in the {@link
   * com.handmark.pulltorefresh.library.PullToRefreshBase.State#RESET} state.
   */
  protected void onReset() {
    mIsBeingDragged = false;
    mLayoutVisibilityChangesEnabled = true;

    // Always reset both layouts, just in case...
    mHeaderLayout.reset();
    mFooterLayout.reset();

    smoothScrollTo(0);
  }
  /**
   * 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();
  }
  @Override
  protected void onReset() {
    /** If the extras are not enabled, just call up to super and return. */
    if (!mListViewExtrasEnabled) {
      super.onReset();
      return;
    }

    final LoadingLayout originalLoadingLayout, listViewLoadingLayout;
    final int scrollToHeight, selection;
    final boolean scrollLvToEdge;

    switch (getCurrentMode()) {
      case MANUAL_REFRESH_ONLY:
      case PULL_FROM_END:
        originalLoadingLayout = getFooterLayout();
        listViewLoadingLayout = mFooterLoadingView;
        selection = mRefreshableView.getCount() - 1;
        scrollToHeight = getFooterSize();
        scrollLvToEdge = Math.abs(mRefreshableView.getLastVisiblePosition() - selection) <= 1;
        break;
      case PULL_FROM_START:
      default:
        originalLoadingLayout = getHeaderLayout();
        listViewLoadingLayout = mHeaderLoadingView;
        scrollToHeight = -getHeaderSize();
        selection = 0;
        scrollLvToEdge = Math.abs(mRefreshableView.getFirstVisiblePosition() - selection) <= 1;
        break;
    }

    // If the ListView header loading layout is showing, then we need to
    // flip so that the original one is showing instead
    if (listViewLoadingLayout.getVisibility() == View.VISIBLE) {

      // Set our Original View to Visible
      originalLoadingLayout.showInvisibleViews();

      // Hide the ListView Header/Footer
      listViewLoadingLayout.setVisibility(View.GONE);

      /**
       * Scroll so the View is at the same Y as the ListView header/footer, but only scroll if:
       * we've pulled to refresh, it's positioned correctly
       */
      if (scrollLvToEdge && getState() != State.MANUAL_REFRESHING) {
        mRefreshableView.setSelection(selection);
        setHeaderScroll(scrollToHeight);
      }
    }

    // Finally, call up to super
    super.onReset();
  }
  @Override
  protected void setRefreshingInternal(boolean doScroll) {

    // If we're empty, then the header/footer views won't show so we use the
    // normal method
    ListAdapter adapter = mRefreshableView.getAdapter();
    if (null == adapter || adapter.isEmpty()) {
      super.setRefreshingInternal(doScroll);
      return;
    }

    super.setRefreshingInternal(false);

    final LoadingLayout originalLoadingLayout, listViewLoadingLayout;
    final int selection, scrollToY;

    switch (getCurrentMode()) {
      case MODE_PULL_UP_TO_REFRESH:
        originalLoadingLayout = getFooterLayout();
        listViewLoadingLayout = mFooterLoadingView;
        selection = mRefreshableView.getCount() - 1;
        scrollToY = getScrollY() - getHeaderHeight();
        break;
      case MODE_PULL_DOWN_TO_REFRESH:
      default:
        originalLoadingLayout = getHeaderLayout();
        listViewLoadingLayout = mHeaderLoadingView;
        selection = 0;
        scrollToY = getScrollY() + getHeaderHeight();
        break;
    }

    if (doScroll) {
      // We scroll slightly so that the ListView's header/footer is at the
      // same Y position as our normal header/footer
      setHeaderScroll(scrollToY);
    }

    // Hide our original Loading View
    originalLoadingLayout.setVisibility(View.INVISIBLE);

    // Show the ListView Loading View and set it to refresh
    listViewLoadingLayout.setVisibility(View.VISIBLE);
    listViewLoadingLayout.refreshing();

    if (doScroll) {
      // Make sure the ListView is scrolled to show the loading
      // header/footer
      mRefreshableView.setSelection(selection);

      // Smooth scroll as normal
      smoothScrollTo(0);
    }
  }
  /**
   * Set the Last Updated Text. This displayed under the main label when Pulling
   *
   * @param label - Label to set
   */
  public void setLastUpdatedLabel(CharSequence label) {
    if (null != mHeaderLayout) {
      mHeaderLayout.setSubHeaderText(label);
    }
    if (null != mFooterLayout) {
      mFooterLayout.setSubHeaderText(label);
    }

    // Refresh Height as it may have changed
    refreshLoadingViewsHeight();
  }
  protected void resetHeader() {
    mState = PULL_TO_REFRESH;
    mIsBeingDragged = false;

    if (mMode.canPullDown()) {
      mHeaderLayout.reset();
    }
    if (mMode.canPullUp()) {
      mFooterLayout.reset();
    }

    smoothScrollTo(0);
  }
 /**
  * Called when the UI has been to be updated to be in the {@link
  * com.handmark.pulltorefresh.library.PullToRefreshBase.State#RELEASE_TO_REFRESH} state.
  */
 protected void onReleaseToRefresh() {
   switch (mCurrentMode) {
     case PULL_FROM_END:
       mFooterLayout.releaseToRefresh();
       break;
     case PULL_FROM_START:
       mHeaderLayout.releaseToRefresh();
       break;
     default:
       // NO-OP
       break;
   }
 }
  /**
   * Actions a Pull Event
   *
   * @return true if the Event has been handled, false if there has been no change
   */
  private void pullEvent() {
    final int newScrollValue;
    final int itemDimension;
    final float initialMotionValue, lastMotionValue;

    switch (getPullToRefreshScrollDirection()) {
      case HORIZONTAL:
        initialMotionValue = mInitialMotionX;
        lastMotionValue = mLastMotionX;
        break;
      case VERTICAL:
      default:
        initialMotionValue = mInitialMotionY;
        lastMotionValue = mLastMotionY;
        break;
    }

    switch (mCurrentMode) {
      case PULL_FROM_END:
        newScrollValue = Math.round(Math.max(initialMotionValue - lastMotionValue, 0) / FRICTION);
        itemDimension = getFooterSize();
        break;
      case PULL_FROM_START:
      default:
        newScrollValue = Math.round(Math.min(initialMotionValue - lastMotionValue, 0) / FRICTION);
        itemDimension = getHeaderSize();
        break;
    }

    setHeaderScroll(newScrollValue);

    if (newScrollValue != 0 && !isRefreshing()) {
      float scale = Math.abs(newScrollValue) / (float) itemDimension;
      switch (mCurrentMode) {
        case PULL_FROM_END:
          mFooterLayout.onPull(scale);
          break;
        case PULL_FROM_START:
        default:
          mHeaderLayout.onPull(scale);
          break;
      }

      if (mState != State.PULL_TO_REFRESH && itemDimension >= Math.abs(newScrollValue)) {
        setState(State.PULL_TO_REFRESH);
      } else if (mState == State.PULL_TO_REFRESH && itemDimension < Math.abs(newScrollValue)) {
        setState(State.RELEASE_TO_REFRESH);
      }
    }
  }
  /** 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);
  }
  @Override
  protected void resetHeader() {

    // If we're empty, then the header/footer views won't show so we use the
    // normal method
    ListAdapter adapter = mRefreshableView.getAdapter();
    if (null == adapter || adapter.isEmpty()) {
      super.resetHeader();
      return;
    }

    LoadingLayout originalLoadingLayout;
    LoadingLayout listViewLoadingLayout;

    int scrollToHeight = getHeaderHeight();
    final boolean doScroll;

    switch (getCurrentMode()) {
      case MODE_PULL_UP_TO_REFRESH:
        originalLoadingLayout = getFooterLayout();
        listViewLoadingLayout = mFooterLoadingView;
        doScroll = isReadyForPullUp();
        break;
      case MODE_PULL_DOWN_TO_REFRESH:
      default:
        originalLoadingLayout = getHeaderLayout();
        listViewLoadingLayout = mHeaderLoadingView;
        scrollToHeight *= -1;
        doScroll = isReadyForPullDown();
        break;
    }

    // Set our Original View to Visible
    originalLoadingLayout.setVisibility(View.VISIBLE);

    // Scroll so our View is at the same Y as the ListView header/footer,
    // but only scroll if the ListView is at the top/bottom
    if (doScroll) {
      setHeaderScroll(scrollToHeight);
    }

    // Hide the ListView Header/Footer
    listViewLoadingLayout.setVisibility(View.GONE);

    super.resetHeader();
  }
  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);
      }
    }
  }
  /**
   * Actions a Pull Event
   *
   * @return true if the Event has been handled, false if there has been no change
   */
  private boolean pullEvent() {

    final int newHeight;
    final int oldHeight = getScrollY();

    switch (mCurrentMode) {
      case PULL_UP_TO_REFRESH:
        newHeight = Math.round(Math.max(mInitialMotionY - mLastMotionY, 0) / FRICTION);
        break;
      case PULL_DOWN_TO_REFRESH:
      default:
        newHeight = Math.round(Math.min(mInitialMotionY - mLastMotionY, 0) / FRICTION);
        break;
    }

    setHeaderScroll(newHeight);

    if (newHeight != 0) {

      float scale = Math.abs(newHeight) / (float) mHeaderHeight;
      switch (mCurrentMode) {
        case PULL_UP_TO_REFRESH:
          mFooterLayout.onPullY(scale);
          break;
        case PULL_DOWN_TO_REFRESH:
          mHeaderLayout.onPullY(scale);
          break;
      }

      if (mState == PULL_TO_REFRESH && mHeaderHeight < Math.abs(newHeight)) {
        mState = RELEASE_TO_REFRESH;
        onReleaseToRefresh();
        return true;

      } else if (mState == RELEASE_TO_REFRESH && mHeaderHeight >= Math.abs(newHeight)) {
        mState = PULL_TO_REFRESH;
        onPullToRefresh();
        return true;
      }
    }

    return oldHeight != newHeight;
  }
  /**
   * Helper method which just calls scrollTo() in the correct scrolling direction.
   *
   * @param value - New Scroll value
   */
  protected final void setHeaderScroll(int value) {
    if (DEBUG) {
      Log.d(LOG_TAG, "setHeaderScroll: " + value);
    }

    // Clamp value to with pull scroll range
    final int maximumPullScroll = getMaximumPullScroll();
    value = Math.min(maximumPullScroll, Math.max(-maximumPullScroll, value));

    if (mLayoutVisibilityChangesEnabled) {
      if (value < 0) {
        mHeaderLayout.setVisibility(View.VISIBLE);
      } else if (value > 0) {
        mFooterLayout.setVisibility(View.VISIBLE);
      } else {
        mHeaderLayout.setVisibility(View.INVISIBLE);
        mFooterLayout.setVisibility(View.INVISIBLE);
      }
    }

    if (USE_HW_LAYERS) {
      /**
       * Use a Hardware Layer on the Refreshable View if we've scrolled at all. We don't use them on
       * the Header/Footer Views as they change often, which would negate any HW layer performance
       * boost.
       */
      ViewCompat.setLayerType(
          mRefreshableViewWrapper, value != 0 ? 2 /*
                                                                             * View.
                                                                             * LAYER_TYPE_HARDWARE
                                                                             */ : 0 /* View.LAYER_TYPE_NONE */);
    }

    switch (getPullToRefreshScrollDirection()) {
      case VERTICAL:
        scrollTo(0, value);
        break;
      case HORIZONTAL:
        scrollTo(value, 0);
        break;
    }
  }
  @Override
  protected final ListView createRefreshableView(Context context, AttributeSet attrs) {
    ListView lv = new InternalListView(context, attrs);

    final int mode = getMode();

    // Loading View Strings
    String pullLabel = context.getString(R.string.pull_to_refresh_pull_label);
    String refreshingLabel = context.getString(R.string.pull_to_refresh_refreshing_label);
    String releaseLabel = context.getString(R.string.pull_to_refresh_release_label);

    // Add Loading Views
    if (mode == MODE_PULL_DOWN_TO_REFRESH || mode == MODE_BOTH) {
      FrameLayout frame = new FrameLayout(context);
      mHeaderLoadingView =
          new LoadingLayout(
              context, MODE_PULL_DOWN_TO_REFRESH, releaseLabel, pullLabel, refreshingLabel);
      frame.addView(
          mHeaderLoadingView,
          FrameLayout.LayoutParams.FILL_PARENT,
          FrameLayout.LayoutParams.WRAP_CONTENT);
      mHeaderLoadingView.setVisibility(View.GONE);
      lv.addHeaderView(frame, null, false);
    }
    if (mode == MODE_PULL_UP_TO_REFRESH || mode == MODE_BOTH) {
      mLvFooterLoadingFrame = new FrameLayout(context);
      mFooterLoadingView =
          new LoadingLayout(
              context, MODE_PULL_UP_TO_REFRESH, releaseLabel, pullLabel, refreshingLabel);
      mLvFooterLoadingFrame.addView(
          mFooterLoadingView,
          FrameLayout.LayoutParams.FILL_PARENT,
          FrameLayout.LayoutParams.WRAP_CONTENT);
      mFooterLoadingView.setVisibility(View.GONE);
    }

    // Set it to this so it can be used in ListActivity/ListFragment
    lv.setId(android.R.id.list);
    return lv;
  }
 protected void handleStyledAttributes(TypedArray typedarray)
 {
     super.handleStyledAttributes(typedarray);
     p = typedarray.getBoolean(14, true);
     if (p)
     {
         android.widget.FrameLayout.LayoutParams layoutparams = new android.widget.FrameLayout.LayoutParams(-1, -2, 1);
         FrameLayout framelayout = new FrameLayout(getContext());
         m = createLoadingLayout(getContext(), PullToRefreshBase.Mode.PULL_FROM_START, typedarray);
         m.setVisibility(8);
         framelayout.addView(m, layoutparams);
         ((ListView)l).addHeaderView(framelayout, null, false);
         o = new FrameLayout(getContext());
         n = createLoadingLayout(getContext(), PullToRefreshBase.Mode.PULL_FROM_END, typedarray);
         n.setVisibility(8);
         o.addView(n, layoutparams);
         if (!typedarray.hasValue(13))
         {
             setScrollingWhileRefreshingEnabled(true);
         }
     }
 }
  /**
   * 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();
    }
  }
 protected final int getFooterSize() {
   return mFooterLayout.getContentSize();
 }
 protected final int getHeaderSize() {
   return mHeaderLayout.getContentSize();
 }
  @Override
  protected void onRefreshing(final boolean doScroll) {
    /**
     * If we're not showing the Refreshing view, or the list is empty, the the header/footer views
     * won't show so we use the normal method.
     */
    ListAdapter adapter = mRefreshableView.getAdapter();
    if (!mListViewExtrasEnabled
        || !getShowViewWhileRefreshing()
        || null == adapter
        || adapter.isEmpty()) {
      super.onRefreshing(doScroll);
      return;
    }

    super.onRefreshing(false);

    final LoadingLayout origLoadingView, listViewLoadingView, oppositeListViewLoadingView;
    final int selection, scrollToY;

    switch (getCurrentMode()) {
      case MANUAL_REFRESH_ONLY:
      case PULL_FROM_END:
        origLoadingView = getFooterLayout();
        listViewLoadingView = mFooterLoadingView;
        oppositeListViewLoadingView = mHeaderLoadingView;
        selection = mRefreshableView.getCount() - 1;
        scrollToY = getScrollY() - getFooterSize();
        break;
      case PULL_FROM_START:
      default:
        origLoadingView = getHeaderLayout();
        listViewLoadingView = mHeaderLoadingView;
        oppositeListViewLoadingView = mFooterLoadingView;
        selection = 0;
        scrollToY = getScrollY() + getHeaderSize();
        break;
    }

    // Hide our original Loading View
    origLoadingView.reset();
    origLoadingView.hideAllViews();

    // Make sure the opposite end is hidden too
    oppositeListViewLoadingView.setVisibility(View.GONE);

    // Show the ListView Loading View and set it to refresh.
    listViewLoadingView.setVisibility(View.VISIBLE);
    listViewLoadingView.refreshing();

    if (doScroll) {
      // We need to disable the automatic visibility changes for now
      disableLoadingLayoutVisibilityChanges();

      // We scroll slightly so that the ListView's header/footer is at the
      // same Y position as our normal header/footer
      setHeaderScroll(scrollToY);

      // Make sure the ListView is scrolled to show the loading
      // header/footer
      mRefreshableView.setSelection(selection);

      // Smooth scroll as normal
      smoothScrollTo(0);
    }
  }