Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 点击刷新始终可见,并且间隙在列表视图上仍然可见_Android_Android Listview_Pull To Refresh - Fatal编程技术网

Android 点击刷新始终可见,并且间隙在列表视图上仍然可见

Android 点击刷新始终可见,并且间隙在列表视图上仍然可见,android,android-listview,pull-to-refresh,Android,Android Listview,Pull To Refresh,我正在使用pull刷新我的应用程序。当列表大小跨越屏幕时,拉刷新工作正常。但是当大小为1或2时,标题和listview之间会有一个间隙,表示点击刷新 这是我的密码 public class PullToRefreshListView extends ListView implements OnScrollListener { private static final int TAP_TO_REFRESH = 1; private static final int PULL_TO_REFRESH

我正在使用pull刷新我的应用程序。当列表大小跨越屏幕时,拉刷新工作正常。但是当大小为1或2时,标题和listview之间会有一个间隙,表示点击刷新

这是我的密码

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();
}

如何消除间隙并“点击刷新”。

使用此代码

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();
}

}
公共类PullToRefreshListView扩展ListView实现OnScrollListener{
//私有静态最终整数点击至刷新=1;
私有静态最终int PULL_TO_REFRESH=2;
私有静态最终整数释放到刷新=3;
受保护的静态最终int刷新=4;
受保护的静态最终字符串标记=“PullToRefreshListView”;
私有OnRefreshListener mOnRefreshListener;
/**
*每次列表滚动时都将接收通知的侦听器。
*/
私有OnScrollListener-mOnScrollListener;
受保护的平层机;
//标题
私人相对人yout mRefreshView;
私有文本视图mRefreshViewText;
私有图像查看mrefreshview图像;
私人进度条mRefreshViewProgress;
私有文本视图mrefreshViewLastUpdate;
受保护的int mCurrentScrollState;
受保护的int-mRefreshState;
私有旋转动画;
私有旋转动画mReverseFlipAnimation;
私人int mRefreshViewHeight;
私有int mrefreshoriginaltopp添加;
私人内部运动;
私有布尔黑客;
公共PullToRefreshListView(上下文){
超级(上下文);
init(上下文);
}
公共PullToRefreshListView(上下文、属性集属性){
超级(上下文,attrs);
init(上下文);
}
公共PullToRefreshListView(上下文、属性集属性、,
int-defStyle){
超级(上下文、属性、定义样式);
init(上下文);
}
受保护的void init(上下文){
//在代码中加载我们需要的所有动画,而不是通过XML加载
mFlipAnimation=新的旋转动画(0,-180,
相对于自身的旋转,0.5f,
旋转想象。相对于自身,0.5f);
setInterpolator(新的LinearInterpolator());
mFlipAnimation.setDuration(250);
mFlipAnimation.setFillAfter(true);
mReverseFlipAnimation=新的旋转动画(-180,0,
相对于自身的旋转,0.5f,
旋转想象。相对于自身,0.5f);
mReverseFlipAnimation.setInterpolator(新的LinearInterpolator());
mReverseFlipAnimation.setDuration(250);
mReverseFlipAnimation.setFillAfter(true);
mInflater=(LayoutInflater)上下文
.getSystemService(上下文布局\充气机\服务);
//标题
mRefreshView=(相对值)最小充气器。充气(
R.layout.pull_to_refresh_header,this,false);
mRefreshViewText=(TextView)mRefreshView
.findViewById(R.id.pull\u to\u refresh\u text);
mRefreshViewImage=(图像视图)mRefreshView
.findviewbyd(R.id.pull\u到\u刷新\u图像);
mRefreshView进度=(进度栏)mRefreshView
.findViewById(R.id.pull\u to\u refresh\u progress);
mRefreshViewLastUpdated=(文本视图)mRefreshView
.findViewById(R.id.pull\u to\u refresh\u updated\u at);
mRefreshViewImage.setMinimumHeight(50);
mRefreshView.setOnClickListener(新的OnClickRefreshListener());
mRefreshOriginalTopPadding=mRefreshView.getPaddingTop();
mRefreshState=拉取刷新;
addHeaderView(mRefreshView);
super.setOnScrollListener(这个);
测量视图(mRefreshView);
mRefreshViewHeight=mRefreshView.getMeasuredHeight();
}
@凌驾
受保护的无效数据附加到DOWINDOW(){
//必须要求超级连接到窗口,否则它不会在果冻豆中滚动。
super.onAttachedToWindow();
选举(1);
}
@凌驾
public void setAdapter(ListAdapter适配器){
super.setAdapter(适配器);
选举(1);
}
/**
*设置每次访问列表时将接收通知的侦听器
*卷轴。
* 
*@param l
*滚动侦听器。
*/
@凌驾
public void setOnScrollListener(AbsListView.OnScrollListener l){
mOnScrollListener=l;
}
/**
*注册要在刷新此列表时调用的回调。
* 
*@param onRefreshListener
*要运行的回调。
*/
公共void setOnRefreshListener(OnRefreshListener OnRefreshListener){
mOnRefreshListener=onRefreshListener;
}
/**
*设置文本以表示列表上次更新的时间。
* 
*@param最近更新
*最后更新于。
*/
公共void setLastUpdated(字符序列lastUpdated){
if(lastUpdated!=null){
mRefreshViewLastUpdated.setVisibility(View.VISIBLE);
mRefreshViewLastUpdated.setText(lastUpdated);
}否则{
mRefreshViewLastUpdated.setVisibility(View.GONE);
}
}
@SuppressLint(“ClickableViewAccessibility”)
@凌驾
公共布尔onTouchEvent(运动事件){
final int y=(int)event.getY();
MBO=错误;
开关(event.getAction()){
case MotionEvent.ACTION\u UP:
如果(!isVerticalScrollBarEnabled()){
setVerticalScrollBarEnabled(真);
}
if(getFirstVisiblePosition()==0&&mRefreshState!=刷新){
如果((mRefreshView.getBottom()>=mRefreshViewHeight | | mRefreshView
.getTop()>=0)和&mRefreshState==RELEASE\u TO\u REFRESH){
//启动刷新
mRefreshState=刷新;
prepareforefresh();
onRefresh();
}else if(mRefreshView.getBottom()listview.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh() {
                // Do work to refresh the list here.

            }
        });
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();
}

}
<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"
    />