首页 > 代码库 > listview 下拉刷新

listview 下拉刷新

 

 

 

 

 

package import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewTreeObserver.OnGlobalLayoutListener;import android.view.animation.DecelerateInterpolator;import android.widget.ListView;import android.widget.RelativeLayout;import android.widget.Scroller;impor /**  * @name: XSListView  * * @date   *  * @author  * * @copyright   * * @desc: ScrollView nesting this XSListView. XSListView may display all, and can not wrap part of listview *  *//** * @file XListView.java * @package me.maxwin.view * @create Mar 18, 2012 6:28:41 PM * @author   * @description An ListView support (a) Pull down to refresh, (b) Pull up to load more. *         Implement IXListViewListener, and see stopRefresh() / stopLoadMore(). */public class XSListView extends ListView {    private float mLastY = -1; // save event y    private Scroller mScroller; // used for scroll back    // the interface to trigger refresh and load more.    private IXListViewListener mListViewListener;    // -- header view    private XListViewHeader mHeaderView;    // header view content, use it to calculate the Header‘s height. And hide it    // when disable pull refresh.    private RelativeLayout mHeaderViewContent;    private int mHeaderViewHeight; // header view‘s height    private boolean mEnablePullRefresh = true;    private boolean mPullRefreshing = false; // is refreashing.    // for mScroller, scroll back from header or footer.    private int mScrollBack;    private final static int SCROLLBACK_HEADER = 0;    private final static int SCROLL_DURATION = 400; // scroll back duration                                                        // at bottom, trigger                                                        // load more.    private final static float OFFSET_RADIO = 1.8f; // support iOS like pull                                                    // feature.    /**     * @param context     */    public XSListView(Context context) {        super(context);        initWithContext(context);    }    public XSListView(Context context, AttributeSet attrs) {        super(context, attrs);        initWithContext(context);    }    public XSListView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initWithContext(context);    }    private void initWithContext(Context context) {        mScroller = new Scroller(context, new DecelerateInterpolator());        // XListView need the scroll event, and it will dispatch the event to        // user‘s listener (as a proxy).        // init header view        mHeaderView = new XListViewHeader(context);        mHeaderViewContent = (RelativeLayout) mHeaderView.findViewById(R.id.xlistview_header_content);        addHeaderView(mHeaderView);                // init header height        mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {                                @Override            public void onGlobalLayout() {                mHeaderViewHeight = mHeaderViewContent.getHeight();                getViewTreeObserver().removeGlobalOnLayoutListener(this);            }        });    }        /**     * enable or disable pull down refresh feature.     *      * @param enable     */    public void setPullRefreshEnable(boolean enable) {        mEnablePullRefresh = enable;        if (!mEnablePullRefresh) { // disable, hide the content            mHeaderViewContent.setVisibility(View.INVISIBLE);        } else {            mHeaderViewContent.setVisibility(View.VISIBLE);        }    }    /**     * stop refresh, reset header view.     */    public void stopRefresh() {        if (mPullRefreshing == true) {            mPullRefreshing = false;            resetHeaderHeight();        }    }    private void updateHeaderHeight(float delta) {        mHeaderView.setVisiableHeight((int) delta + mHeaderView.getVisiableHeight());        if (mEnablePullRefresh && !mPullRefreshing) { // 未处于刷新状态,更新箭头            if (mHeaderView.getVisiableHeight() > mHeaderViewHeight) {                mHeaderView.setState(XListViewHeader.STATE_READY, mListViewListener.lastUpdateTime());            } else {                mHeaderView.setState(XListViewHeader.STATE_NORMAL, mListViewListener.lastUpdateTime());            }        }        setSelection(0); // scroll to top each time    }    /**     * reset header view‘s height.     */    private void resetHeaderHeight() {        int height = mHeaderView.getVisiableHeight();        if (height == 0) // not visible.            return;        // refreshing and header isn‘t shown fully. do nothing.        if (mPullRefreshing && height <= mHeaderViewHeight) {            return;        }        int finalHeight = 0; // default: scroll back to dismiss header.        // is refreshing, just scroll back to show all the header.        if (mPullRefreshing && height > mHeaderViewHeight) finalHeight = mHeaderViewHeight;        mScrollBack = SCROLLBACK_HEADER;        mScroller.startScroll(0, height, 0, finalHeight - height, SCROLL_DURATION);        // trigger computeScroll        invalidate();    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        if (mLastY == -1) {            mLastY = ev.getRawY();        }        switch (ev.getAction()) {        case MotionEvent.ACTION_DOWN:            mLastY = ev.getRawY();            break;        case MotionEvent.ACTION_MOVE:            final float deltaY = ev.getRawY() - mLastY;            mLastY = ev.getRawY();            if (getFirstVisiblePosition() == 0 && (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) {                // the first item is showing, header has shown or pull down.                updateHeaderHeight(deltaY / OFFSET_RADIO);            }            break;        default:            mLastY = -1; // reset            if (getFirstVisiblePosition() == 0) {                // invoke refresh                if (mEnablePullRefresh && mHeaderView.getVisiableHeight() > mHeaderViewHeight) {                    mPullRefreshing = true;                    mHeaderView.setState(XListViewHeader.STATE_REFRESHING,"");                    if (mListViewListener != null) {                        mListViewListener.onRefresh();                    }                }                resetHeaderHeight();            }             break;        }        return super.onTouchEvent(ev);    }    @Override    public void computeScroll() {        if (mScroller.computeScrollOffset()) {            if (mScrollBack == SCROLLBACK_HEADER) mHeaderView.setVisiableHeight(mScroller.getCurrY());            postInvalidate();        }        super.computeScroll();    }    public void setXListViewListener(IXListViewListener l) {        mListViewListener = l;    }    /**     * implements this interface to get refresh/load more event.     */    public interface IXListViewListener {        public void onRefresh();        public String lastUpdateTime();    }}

 

 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3     android:layout_width="fill_parent" 4     android:layout_height="wrap_content" 5     android:gravity="bottom" > 6  7     <RelativeLayout 8         android:id="@+id/xlistview_header_content" 9         android:layout_width="fill_parent"10         android:layout_height="50dp" >11 12         <LinearLayout13             android:id="@+id/xlistview_header_text"14             android:layout_width="wrap_content"15             android:layout_height="wrap_content"16             android:layout_centerInParent="true"17             android:gravity="center"18             android:orientation="vertical" >19 20             <TextView21                 android:id="@+id/xlistview_header_hint_textview"22                 android:layout_width="wrap_content"23                 android:layout_height="wrap_content"24                 android:text="@string/xlistview_header_hint_normal"25                 android:textSize="13sp" />26 27             <TextView28                 android:id="@+id/xlistview_header_time"29                 android:layout_width="wrap_content"30                 android:layout_height="wrap_content"31                 android:text="更新时间:"32                 android:textSize="12sp" />33         </LinearLayout>34 35         <ImageView36             android:id="@+id/xlistview_header_arrow"37             android:layout_width="wrap_content"38             android:layout_height="wrap_content"39             android:layout_alignLeft="@id/xlistview_header_text"40             android:layout_centerVertical="true"41             android:layout_marginLeft="-35dp"42             android:contentDescription="@string/app_name"43             android:src="@drawable/xlistview_arrow" />44 45         <ProgressBar46             android:id="@+id/xlistview_header_progressbar"47             android:layout_width="30dp"48             android:layout_height="30dp"49             android:layout_alignLeft="@id/xlistview_header_text"50             android:layout_centerVertical="true"51             android:layout_marginLeft="-40dp"52             android:visibility="invisible" />53     </RelativeLayout>54 55 </LinearLayout>

 

listview 下拉刷新