码迷,mamicode.com
首页 > 其他好文 > 详细

listview 下拉刷新

时间:2014-10-27 15:33:50      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:des   android   style   blog   http   io   color   os   ar   

 

 

 

 

 

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         <LinearLayout
13             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             <TextView
21                 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             <TextView
28                 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         <ImageView
36             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         <ProgressBar
46             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 下拉刷新

标签:des   android   style   blog   http   io   color   os   ar   

原文地址:http://www.cnblogs.com/flyingsir/p/4054283.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!