点击刷新始终可见,并且列表视图上仍可显示间隙

时间:2013-07-01 08:33:26

标签: android android-listview pull-to-refresh

我在我的应用程序中使用pull来刷新。当列表大小超过屏幕时,拉到刷新工作正常。但是当大小为一或两个时,标题和列表视图之间存在间隙,表示点击以刷新。

这是我的代码

public class PullToRefreshListView extends ListView implements OnScrollListener {

private static final int TAP_TO_REFRESH = 1;
private static final int PULL_TO_REFRESH = 2;
private static final int RELEASE_TO_REFRESH = 3;
private static final int REFRESHING = 4;

private static final String TAG = "PullToRefreshListView";

private OnRefreshListener mOnRefreshListener;

/**
 * Listener that will receive notifications every time the list scrolls.
 */
private OnScrollListener mOnScrollListener;
private LayoutInflater mInflater;

private RelativeLayout mRefreshView;
private TextView mRefreshViewText;
private ImageView mRefreshViewImage;
private ProgressBar mRefreshViewProgress;
private TextView mRefreshViewLastUpdated;

private int mCurrentScrollState;
private int mRefreshState;

private RotateAnimation mFlipAnimation;
private RotateAnimation mReverseFlipAnimation;

private int mRefreshViewHeight;
private int mRefreshOriginalTopPadding;
private int mLastMotionY;

private boolean mBounceHack;

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

public PullToRefreshListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public PullToRefreshListView(Context context, AttributeSet attrs,
        int defStyle) {
    super(context, attrs, defStyle);
    init(context);
}

private void init(Context context) {
    // Load all of the animations we need in code rather than through XML
    mFlipAnimation = new RotateAnimation(0, -180,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    mFlipAnimation.setInterpolator(new LinearInterpolator());
    mFlipAnimation.setDuration(250);
    mFlipAnimation.setFillAfter(true);
    mReverseFlipAnimation = new RotateAnimation(-180, 0,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
    mReverseFlipAnimation.setDuration(250);
    mReverseFlipAnimation.setFillAfter(true);

    mInflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    mRefreshView = (RelativeLayout) mInflater.inflate(
            R.layout.pull_to_refresh_header, this, false);
    mRefreshViewText = (TextView) mRefreshView
            .findViewById(R.id.pull_to_refresh_text);
    mRefreshViewImage = (ImageView) mRefreshView
            .findViewById(R.id.pull_to_refresh_image);
    mRefreshViewProgress = (ProgressBar) mRefreshView
            .findViewById(R.id.pull_to_refresh_progress);
    mRefreshViewLastUpdated = (TextView) mRefreshView
            .findViewById(R.id.pull_to_refresh_updated_at);

    mRefreshViewImage.setMinimumHeight(50);
    mRefreshView.setOnClickListener(new OnClickRefreshListener());
    mRefreshOriginalTopPadding = mRefreshView.getPaddingTop();

    mRefreshState = TAP_TO_REFRESH;

    addHeaderView(mRefreshView);

    super.setOnScrollListener(this);

    measureView(mRefreshView);
    mRefreshViewHeight = mRefreshView.getMeasuredHeight();
}

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    setSelection(1);
}

@Override
public void setAdapter(ListAdapter adapter) {
    super.setAdapter(adapter);

    setSelection(1);
}

/**
 * Set the listener that will receive notifications every time the list
 * scrolls.
 * 
 * @param l
 *            The scroll listener.
 */
@Override
public void setOnScrollListener(AbsListView.OnScrollListener l) {
    mOnScrollListener = l;
}

/**
 * Register a callback to be invoked when this list should be refreshed.
 * 
 * @param onRefreshListener
 *            The callback to run.
 */
public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
    mOnRefreshListener = onRefreshListener;
}

/**
 * Set a text to represent when the list was last updated.
 * 
 * @param lastUpdated
 *            Last updated at.
 */
public void setLastUpdated(CharSequence lastUpdated) {
    if (lastUpdated != null) {
        mRefreshViewLastUpdated.setVisibility(View.VISIBLE);
        mRefreshViewLastUpdated.setText(lastUpdated);
    } else {
        mRefreshViewLastUpdated.setVisibility(View.GONE);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    final int y = (int) event.getY();
    mBounceHack = false;

    switch (event.getAction()) {
    case MotionEvent.ACTION_UP:
        if (!isVerticalScrollBarEnabled()) {
            setVerticalScrollBarEnabled(true);
        }
        if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) {
            if ((mRefreshView.getBottom() >= mRefreshViewHeight || mRefreshView
                    .getTop() >= 0) && mRefreshState == RELEASE_TO_REFRESH) {
                // Initiate the refresh
                mRefreshState = REFRESHING;
                prepareForRefresh();
                onRefresh();
            } else if (mRefreshView.getBottom() < mRefreshViewHeight
                    || mRefreshView.getTop() <= 0) {
                // Abort refresh and scroll down below the refresh view
                resetHeader();
                setSelection(1);
            }
        }
        break;
    case MotionEvent.ACTION_DOWN:
        mLastMotionY = y;
        break;
    case MotionEvent.ACTION_MOVE:
        applyHeaderPadding(event);
        break;
    }
    return super.onTouchEvent(event);
}

private void applyHeaderPadding(MotionEvent ev) {
    // getHistorySize has been available since API 1
    int pointerCount = ev.getHistorySize();

    for (int p = 0; p < pointerCount; p++) {
        if (mRefreshState == RELEASE_TO_REFRESH) {
            if (isVerticalFadingEdgeEnabled()) {
                setVerticalScrollBarEnabled(false);
            }

            int historicalY = (int) ev.getHistoricalY(p);

            // Calculate the padding to apply, we divide by 1.7 to
            // simulate a more resistant effect during pull.
            int topPadding = (int) (((historicalY - mLastMotionY) - mRefreshViewHeight) / 1.7);

            mRefreshView.setPadding(mRefreshView.getPaddingLeft(),
                    topPadding, mRefreshView.getPaddingRight(),
                    mRefreshView.getPaddingBottom());
        }
    }
}

/**
 * Sets the header padding back to original size.
 */
private void resetHeaderPadding() {
    mRefreshView.setPadding(mRefreshView.getPaddingLeft(),
            mRefreshOriginalTopPadding, mRefreshView.getPaddingRight(),
            mRefreshView.getPaddingBottom());
}

/**
 * Resets the header to the original state.
 */
private void resetHeader() {
    if (mRefreshState != TAP_TO_REFRESH) {
        mRefreshState = TAP_TO_REFRESH;

        resetHeaderPadding();

        // Set refresh view text to the pull label
        mRefreshViewText.setText(R.string.pull_to_refresh_tap_label);
        // Replace refresh drawable with arrow drawable
        mRefreshViewImage
                .setImageResource(R.drawable.ic_pulltorefresh_arrow);
        // Clear the full rotation animation
        mRefreshViewImage.clearAnimation();
        // Hide progress bar and arrow.
        mRefreshViewImage.setVisibility(View.GONE);
        mRefreshViewProgress.setVisibility(View.GONE);
    }
}

private void measureView(View child) {
    ViewGroup.LayoutParams p = child.getLayoutParams();
    if (p == null) {
        p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
    int lpHeight = p.height;
    int childHeightSpec;
    if (lpHeight > 0) {
        childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                MeasureSpec.EXACTLY);
    } else {
        childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
    }
    child.measure(childWidthSpec, childHeightSpec);
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
    // When the refresh view is completely visible, change the text to say
    // "Release to refresh..." and flip the arrow drawable.
    if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL
            && mRefreshState != REFRESHING) {
        if (firstVisibleItem == 0) {
            mRefreshViewImage.setVisibility(View.VISIBLE);
            if ((mRefreshView.getBottom() >= mRefreshViewHeight + 20 || mRefreshView
                    .getTop() >= 0) && mRefreshState != RELEASE_TO_REFRESH) {
                mRefreshViewText
                        .setText(R.string.pull_to_refresh_release_label);
                mRefreshViewImage.clearAnimation();
                mRefreshViewImage.startAnimation(mFlipAnimation);
                mRefreshState = RELEASE_TO_REFRESH;
            } else if (mRefreshView.getBottom() < mRefreshViewHeight + 20
                    && mRefreshState != PULL_TO_REFRESH) {
                mRefreshViewText
                        .setText(R.string.pull_to_refresh_pull_label);
                if (mRefreshState != TAP_TO_REFRESH) {
                    mRefreshViewImage.clearAnimation();
                    mRefreshViewImage.startAnimation(mReverseFlipAnimation);
                }
                mRefreshState = PULL_TO_REFRESH;
            }
        } else {
            mRefreshViewImage.setVisibility(View.GONE);
            resetHeader();
        }
    } else if (mCurrentScrollState == SCROLL_STATE_FLING
            && firstVisibleItem == 0 && mRefreshState != REFRESHING) {
        setSelection(1);
        mBounceHack = true;
    } else if (mBounceHack && mCurrentScrollState == SCROLL_STATE_FLING) {
        setSelection(1);
    }

    if (mOnScrollListener != null) {
        mOnScrollListener.onScroll(view, firstVisibleItem,
                visibleItemCount, totalItemCount);
    }
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    mCurrentScrollState = scrollState;

    if (mCurrentScrollState == SCROLL_STATE_IDLE) {
        mBounceHack = false;
    }

    if (mOnScrollListener != null) {
        mOnScrollListener.onScrollStateChanged(view, scrollState);
    }
}

public void prepareForRefresh() {
    resetHeaderPadding();

    mRefreshViewImage.setVisibility(View.GONE);
    // We need this hack, otherwise it will keep the previous drawable.
    mRefreshViewImage.setImageDrawable(null);
    mRefreshViewProgress.setVisibility(View.VISIBLE);

    // Set refresh view text to the refreshing label
    mRefreshViewText.setText(R.string.pull_to_refresh_refreshing_label);

    mRefreshState = REFRESHING;
}

public void onRefresh() {
    Log.d(TAG, "onRefresh");

    if (mOnRefreshListener != null) {
        mOnRefreshListener.onRefresh();
    }
}

/**
 * Resets the list to a normal state after a refresh.
 * 
 * @param lastUpdated
 *            Last updated at.
 */
public void onRefreshComplete(CharSequence lastUpdated) {
    setLastUpdated(lastUpdated);
    onRefreshComplete();
}

/**
 * Resets the list to a normal state after a refresh.
 */
public void onRefreshComplete() {
    Log.d(TAG, "onRefreshComplete");

    resetHeader();

    // If refresh view is visible when loading completes, scroll down to
    // the next item.
    if (mRefreshView.getBottom() > 0) {
        invalidateViews();
        setSelection(1);
    }
}

/**
 * Invoked when the refresh view is clicked on. This is mainly used when
 * there's only a few items in the list and it's not possible to drag the
 * list.
 */
private class OnClickRefreshListener implements OnClickListener {

    @Override
    public void onClick(View v) {
        if (mRefreshState != REFRESHING) {
            prepareForRefresh();
            onRefresh();
        }
    }

}

/**
 * Interface definition for a callback to be invoked when list should be
 * refreshed.
 */
public interface OnRefreshListener {
    /**
     * Called when the list should be refreshed.
     * <p>
     * A call to {@link PullToRefreshListView #onRefreshComplete()} is
     * expected to indicate that the refresh has completed.
     */
    public void onRefresh();
}

}

这是我的xml代码

            <com.k2b.kluebook.pulltorefresh.PullToRefreshListView
            android:id="@+id/list_pulltorefresh"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:divider="@null"
            android:dividerHeight="0dp" >
        </com.k2b.kluebook.pulltorefresh.PullToRefreshListView>

这是我的班级文件代码

listview.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh() {
                // Do work to refresh the list here.

            }
        });

Here is the image with gap between the header

If the gap is clicked Tap is showing

如何摆脱GAP和“点击刷新”。

1 个答案:

答案 0 :(得分:2)

请改用此代码

public class PullToRefreshListView extends ListView implements OnScrollListener {

//  private static final int TAP_TO_REFRESH = 1;
private static final int PULL_TO_REFRESH = 2;
private static final int RELEASE_TO_REFRESH = 3;
protected static final int REFRESHING = 4;

protected static final String TAG = "PullToRefreshListView";

private OnRefreshListener mOnRefreshListener;

/**
 * Listener that will receive notifications every time the list scrolls.
 */
private OnScrollListener mOnScrollListener;
protected LayoutInflater mInflater;

// header
private RelativeLayout mRefreshView;
private TextView mRefreshViewText;
private ImageView mRefreshViewImage;
private ProgressBar mRefreshViewProgress;
private TextView mRefreshViewLastUpdated;

protected int mCurrentScrollState;
protected int mRefreshState;

private RotateAnimation mFlipAnimation;
private RotateAnimation mReverseFlipAnimation;

private int mRefreshViewHeight;
private int mRefreshOriginalTopPadding;
private int mLastMotionY;

private boolean mBounceHack;

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

public PullToRefreshListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public PullToRefreshListView(Context context, AttributeSet attrs,
        int defStyle) {
    super(context, attrs, defStyle);
    init(context);
}

protected void init(Context context) {
    // Load all of the animations we need in code rather than through XML
    mFlipAnimation = new RotateAnimation(0, -180,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    mFlipAnimation.setInterpolator(new LinearInterpolator());
    mFlipAnimation.setDuration(250);
    mFlipAnimation.setFillAfter(true);
    mReverseFlipAnimation = new RotateAnimation(-180, 0,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
    mReverseFlipAnimation.setDuration(250);
    mReverseFlipAnimation.setFillAfter(true);

    mInflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    // header
    mRefreshView = (RelativeLayout) mInflater.inflate(
            R.layout.pull_to_refresh_header, this, false);
    mRefreshViewText = (TextView) mRefreshView
            .findViewById(R.id.pull_to_refresh_text);
    mRefreshViewImage = (ImageView) mRefreshView
            .findViewById(R.id.pull_to_refresh_image);
    mRefreshViewProgress = (ProgressBar) mRefreshView
            .findViewById(R.id.pull_to_refresh_progress);
    mRefreshViewLastUpdated = (TextView) mRefreshView
            .findViewById(R.id.pull_to_refresh_updated_at);

    mRefreshViewImage.setMinimumHeight(50);
    mRefreshView.setOnClickListener(new OnClickRefreshListener());
    mRefreshOriginalTopPadding = mRefreshView.getPaddingTop();

    mRefreshState = PULL_TO_REFRESH;

    addHeaderView(mRefreshView);

    super.setOnScrollListener(this);

    measureView(mRefreshView);
    mRefreshViewHeight = mRefreshView.getMeasuredHeight();
}

@Override
protected void onAttachedToWindow() {
    //have to ask super to attach to window, otherwise it won't scroll in jelly bean.
    super.onAttachedToWindow();
    setSelection(1);
}

@Override
public void setAdapter(ListAdapter adapter) {
    super.setAdapter(adapter);

    setSelection(1);
}

/**
 * Set the listener that will receive notifications every time the list
 * scrolls.
 * 
 * @param l
 *            The scroll listener.
 */
@Override
public void setOnScrollListener(AbsListView.OnScrollListener l) {
    mOnScrollListener = l;
}

/**
 * Register a callback to be invoked when this list should be refreshed.
 * 
 * @param onRefreshListener
 *            The callback to run.
 */
public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
    mOnRefreshListener = onRefreshListener;
}

/**
 * Set a text to represent when the list was last updated.
 * 
 * @param lastUpdated
 *            Last updated at.
 */
public void setLastUpdated(CharSequence lastUpdated) {
    if (lastUpdated != null) {
        mRefreshViewLastUpdated.setVisibility(View.VISIBLE);
        mRefreshViewLastUpdated.setText(lastUpdated);
    } else {
        mRefreshViewLastUpdated.setVisibility(View.GONE);
    }
}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
    final int y = (int) event.getY();
    mBounceHack = false;

    switch (event.getAction()) {
    case MotionEvent.ACTION_UP:
        if (!isVerticalScrollBarEnabled()) {
            setVerticalScrollBarEnabled(true);
        }
        if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) {
            if ((mRefreshView.getBottom() >= mRefreshViewHeight || mRefreshView
                    .getTop() >= 0) && mRefreshState == RELEASE_TO_REFRESH) {
                // Initiate the refresh
                mRefreshState = REFRESHING;
                prepareForRefresh();
                onRefresh();
            } else if (mRefreshView.getBottom() < mRefreshViewHeight
                    || mRefreshView.getTop() <= 0) {
                // Abort refresh and scroll down below the refresh view
                resetHeader();
                setSelection(1);
            }
        }
        break;
    case MotionEvent.ACTION_DOWN:
        mLastMotionY = y;
        break;
    case MotionEvent.ACTION_MOVE:
        applyHeaderPadding(event);
        break;
    }
    return super.onTouchEvent(event);
}

private void applyHeaderPadding(MotionEvent ev) {
    // getHistorySize has been available since API 1
    int pointerCount = ev.getHistorySize();

    for (int p = 0; p < pointerCount; p++) {
//          if (mRefreshState == RELEASE_TO_REFRESH) {
            if (isVerticalFadingEdgeEnabled()) {
                setVerticalScrollBarEnabled(false);
            }

            int historicalY = (int) ev.getHistoricalY(p);

            // Calculate the padding to apply, we divide by 1.7 to
            // simulate a more resistant effect during pull.
            int topPadding = (int) (((historicalY - mLastMotionY) - mRefreshViewHeight) / 1.7);

            mRefreshView.setPadding(mRefreshView.getPaddingLeft(),
                    topPadding, mRefreshView.getPaddingRight(),
                    mRefreshView.getPaddingBottom());
        }
//      }
}

/**
 * Sets the header padding back to original size.
 */
private void resetHeaderPadding() {
    mLastMotionY = 0;
    mRefreshView.setPadding(mRefreshView.getPaddingLeft(),
            mRefreshOriginalTopPadding, mRefreshView.getPaddingRight(),
            mRefreshView.getPaddingBottom());
}

/**
 * Resets the header to the original state.
 */
private void resetHeader() {
//      if (mRefreshState != TAP_TO_REFRESH) {
        mRefreshState = PULL_TO_REFRESH;

        resetHeaderPadding();

        // Set refresh view text to the pull label
        mRefreshViewText.setText(R.string.pull_to_refresh_tap_label);
        // Replace refresh drawable with arrow drawable
        mRefreshViewImage
                .setImageResource(R.drawable.ic_pulltorefresh_arrow);
        // Clear the full rotation animation
        mRefreshViewImage.clearAnimation();
        // Hide progress bar and arrow.
        mRefreshViewImage.setVisibility(View.GONE);
        mRefreshViewProgress.setVisibility(View.GONE);
//      }
}

private void measureView(View child) {
    ViewGroup.LayoutParams p = child.getLayoutParams();
    if (p == null) {
        p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
    int lpHeight = p.height;
    int childHeightSpec;
    if (lpHeight > 0) {
        childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                MeasureSpec.EXACTLY);
    } else {
        childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
    }
    child.measure(childWidthSpec, childHeightSpec);
}

public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
    // When the refresh view is completely visible, change the text to say
    // "Release to refresh..." and flip the arrow drawable.
    if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL
            && mRefreshState != REFRESHING) {
        if (firstVisibleItem == 0) {
            mRefreshViewImage.setVisibility(View.VISIBLE);
            if ((mRefreshView.getBottom() >= mRefreshViewHeight + 20 || mRefreshView
                    .getTop() >= 0) && mRefreshState != RELEASE_TO_REFRESH) {
                mRefreshViewText
                        .setText(R.string.pull_to_refresh_release_label);
                mRefreshViewImage.clearAnimation();
                mRefreshViewImage.startAnimation(mFlipAnimation);
                mRefreshState = RELEASE_TO_REFRESH;
            } else if (mRefreshView.getBottom() < mRefreshViewHeight + 20
                    && mRefreshState != PULL_TO_REFRESH) {
                mRefreshViewText
                        .setText(R.string.pull_to_refresh_pull_label);
//                  if (mRefreshState != TAP_TO_REFRESH) {
                    mRefreshViewImage.clearAnimation();
                    mRefreshViewImage.startAnimation(mReverseFlipAnimation);
//                  }
                mRefreshState = PULL_TO_REFRESH;
            }
        } else {
            mRefreshViewImage.setVisibility(View.GONE);
            resetHeader();
        }
    } else if (mCurrentScrollState == SCROLL_STATE_FLING
            && firstVisibleItem == 0 && mRefreshState != REFRESHING) {
        setSelection(1);
        mBounceHack = true;
    } else if (mBounceHack && mCurrentScrollState == SCROLL_STATE_FLING) {
        setSelection(1);
    }

    if (mOnScrollListener != null) {
        mOnScrollListener.onScroll(view, firstVisibleItem,
                visibleItemCount, totalItemCount);
    }
}

public void onScrollStateChanged(AbsListView view, int scrollState) {
    mCurrentScrollState = scrollState;

    if (mCurrentScrollState == SCROLL_STATE_IDLE) {
        mBounceHack = false;
    }

    if (mOnScrollListener != null) {
        mOnScrollListener.onScrollStateChanged(view, scrollState);
    }

}

public void prepareForRefresh() {
    resetHeaderPadding();

    mRefreshViewImage.setVisibility(View.GONE);
    // We need this hack, otherwise it will keep the previous drawable.
    mRefreshViewImage.setImageDrawable(null);
    mRefreshViewProgress.setVisibility(View.VISIBLE);

    // Set refresh view text to the refreshing label
    mRefreshViewText.setText(R.string.pull_to_refresh_refreshing_label);

    mRefreshState = REFRESHING;
}

public void onRefresh() {
    Log.d(TAG, "onRefresh");

    if (mOnRefreshListener != null) {
        mOnRefreshListener.onRefresh();
    }
}

/**
 * Resets the list to a normal state after a refresh.
 * 
 * @param lastUpdated
 *            Last updated at.
 */
public void onRefreshComplete(CharSequence lastUpdated) {
    setLastUpdated(lastUpdated);
    onRefreshComplete();
}

/**
 * Resets the list to a normal state after a refresh.
 */
public void onRefreshComplete() {
    Log.d(TAG, "onRefreshComplete");

    resetHeader();

    // If refresh view is visible when loading completes, scroll down to
    // the next item.
    if (mRefreshView.getBottom() > 0) {
        invalidateViews();
        setSelection(1);
    }
}

/**
 * Invoked when the refresh view is clicked on. This is mainly used when
 * there's only a few items in the list and it's not possible to drag the
 * list.
 */
private class OnClickRefreshListener implements OnClickListener {

    public void onClick(View v) {
        if (mRefreshState != REFRESHING) {
            prepareForRefresh();
            onRefresh();
        }
    }

}

/**
 * Interface definition for a callback to be invoked when list should be
 * refreshed.
 */
public interface OnRefreshListener {
    /**
     * Called when the list should be refreshed.
     * <p>
     * A call to {@link PullToRefreshListView #onRefreshComplete()} is
     * expected to indicate that the refresh has completed.
     */
    public void onRefresh();
}

}
如果你有的话,

还可以在库布局的pull_to_refresh_header.xml中设置可见性(android:id =“@ + id / pull_to_refresh_text”)

<TextView
    android:id="@+id/pull_to_refresh_text"
    android:text="@string/pull_to_refresh_pull_label"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textStyle="bold"
    android:paddingTop="5dip"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center"
    android:visibility="gone"
    />

享受!