在android中有时我们要实现下拉刷新的功能,我在前日人的基础上自己实现了一个。
其实实现的原理很简单,显示在listView的headerView中添加一个要刷新的进度条显示设置这个view影藏,在你拖动listView的时候当你托到最上面的时候,进行判断显示,影藏进度条,在显示进度条后你松开手势的时候根据不同的状态实现页面的操作。不多说了,实现的代码如下:
显示声明一个显示进度条的view的布局文件:head.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/head_rootLayout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <!-- 内容 -->

    <RelativeLayout
        android:id="@+id/head_contentLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="30dp" >

        <!-- 箭头图像、进度条 -->

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true" >

            <!-- 箭头 -->

            <ImageView
                android:id="@+id/head_arrowImageView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@drawable/arrow"
               />

            <!-- 进度条 -->

            <ProgressBar
                android:id="@+id/head_progressBar"
                style="?android:attr/progressBarStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:visibility="gone" />
        </FrameLayout>

        <!-- 提示、最近更新 -->

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:gravity="center_horizontal"
            android:orientation="vertical" >

            <!-- 提示 -->

            <TextView
                android:id="@+id/head_tipsTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="下拉刷新"
                android:textColor="#ffffff"
                android:textSize="20sp" />

            <!-- 最近更新 -->

            <TextView
                android:id="@+id/head_lastUpdatedTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="最近更新"
                android:textColor="#cc6600"
                android:textSize="10sp" />
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>




在重写listView实现onScrollListener


public class MyListView extends ListView implements OnScrollListener 
{ 
    /** 
     * 下拉现实的headView 
     */ 
    private View headView; 

    /** 
     * 刷新的箭头的view 
     */ 
    private ImageView arrowImageView; 

    /** 
     * 显示刷新的进度条 
     */ 
    private ProgressBar progressBar = null; 

    /** 
     * 显示提示刷新的提示语句 
     */ 
    private TextView tipsTextView; 

    /** 
     * 显示的第一个Item的view 
     */ 
    private int fistVisibleItem = -1; 

    /** 
     * headView的宽度 
     */ 
    private int headContextWidth=0; 

    /** 
     * 向下箭头的样式 
     */ 
    private Animation todownAnimation; 

    /** 
     * 向上箭头的样式 
     */ 
    private Animation toupAnimation; 

    /** 
     * headView的高度 
     */ 
    private int headContextHeight = 0; 

    /** 
     * 定义当前滑动的状态 
     */ 
    private int state = DONE; 

    /** 
     * 未执行的状态 
     */ 
    private static final int DONE = 0; 

    /** 
     * 即将松开去刷新界面,箭头变为向上 
     */ 
    private static final int RELEATSE_TO_FRESH = 1; 

    /** 
     * 正在加载数据 
     */ 
    private static final int LOADING = 2; 

    /** 
     * 拉动去刷新,调整箭头的位置,箭头向下 
     */ 
    private static final int PULL_TO_REFRESH = 3; 

    /** 
     * 确定当前只有一个开始的位置被记录 
     */ 
    private boolean isRecorded = false; 

    /** 
     * 设置滑动的比例 
     */ 
    private static final int FLING_V = 3; 

    /** 
     * 开始的位置 
     */ 
    private int starty =0; 


    private boolean isback = false; 

    /** 
     * 刷新界面的回调接口 
     */ 
    private OnRefreshListener onRefreshListener; 

    public interface OnRefreshListener 
    { 
        public void onRefresh(); 
    } 


    public MyListView(Context context, AttributeSet attrs, int defStyle) 
    { 
        super(context, attrs, defStyle); 
        initView(); 
    } 

    public MyListView(Context context, AttributeSet attrs) 
    { 
        super(context, attrs); 
        initView(); 
    } 

    public MyListView(Context context) 
    { 
        super(context); 
        initView(); 
    } 

    /** 
     * 初始化要显示的headview 
     * 
     * @see intView 
     */ 
    private void initView() 
    { 
        headView = ((LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.head, null); 
        arrowImageView = (ImageView)headView.findViewById(R.id.head_arrowImageView); 
        progressBar = (ProgressBar)headView.findViewById(R.id.head_progressBar); 
        tipsTextView = (TextView)headView.findViewById(R.id.head_tipsTextView); 

        //重新设置headView的大小 
        resetHeadView(); 
        headContextWidth = headView.getMeasuredWidth(); 
        headContextHeight = headView.getMeasuredHeight(); 

        //设置headView的padding 
        headView.setPadding(0, -headContextHeight, 0, 0); 
        headView.invalidate(); 

        //添加headView到listView的第一个item中去 
        addHeaderView(headView,null,false); 

        setOnScrollListener(this); 

        todownAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f,  Animation.RELATIVE_TO_SELF, 0.5f); 
        todownAnimation.setInterpolator(new LinearInterpolator()); 
        todownAnimation.setDuration(250); 
        todownAnimation.setFillAfter(true); 

        toupAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f,  Animation.RELATIVE_TO_SELF, 0.5f); 
        toupAnimation.setInterpolator(new LinearInterpolator()); 
        toupAnimation.setDuration(250); 
        toupAnimation.setFillAfter(true); 

        state = DONE; 

        isRecorded = false; 
    } 

    /** 
     * 实现listView的触摸的事件 
     * 
     * @param ev 
     * 
     *        点击的事件 
     *        
     * @see onTouchEvent       
     */ 
    @Override 
    public boolean onTouchEvent(MotionEvent ev) 
    { 
        int tempy = 0; 
        switch(ev.getAction()) 
        { 
            //点击的事件 
            case MotionEvent.ACTION_DOWN: 
                if(fistVisibleItem ==0 && !isRecorded) 
                { 
                    isRecorded = true; 
                    starty = (int)ev.getY(); 
                } 
                break; 

            //移动的事件 
            case MotionEvent.ACTION_MOVE: 
                tempy = (int)ev.getY(); 
                if(fistVisibleItem ==0 && !isRecorded) 
                { 
                    isRecorded = true; 
                    starty = (int)ev.getY(); 
                } 

                //当前的用户不在加载数据,并且不在刷新界面的时候 
                if(state != LOADING && isRecorded) 
                { 
                    //可以松开去刷新界面了 
                    if(state == RELEATSE_TO_FRESH) 
                    { 
                        setSelection(0); 
                        //用户在向上推的时候 
                        if((tempy-starty)/FLING_V0) 
                        { 
                            state = PULL_TO_REFRESH; 
                            changeHeadViewState(); 
                        } 
                        //用户快速向上推 
                        else if(tempy-startyheadContextHeight) 
                        { 
                            isback = true; 
                            state = RELEATSE_TO_FRESH; 
                            changeHeadViewState(); 
                        } 
                        //上推到顶了 
                        else if((tempy-starty)/FLING_V0) 
                       { 
                           state = PULL_TO_REFRESH; 
                           changeHeadViewState(); 
                       } 
                    } 

                    //修改显示view的大小 
                    if(state == PULL_TO_REFRESH||state == RELEATSE_TO_FRESH) 
                    { 
                        headView.setPadding(0, -headContextHeight+(tempy-starty)/FLING_V, 0, 0); 
                    } 

                } 
                break; 

            //手势离开控件   
            case MotionEvent.ACTION_UP: 
                if(state != LOADING) 
                { 
                    if(state == PULL_TO_REFRESH) 
                    { 
                        state = DONE; 
                        changeHeadViewState(); 
                    } 
                    else if(state == DONE) 
                    { 

                    } 
                    else if(state == RELEATSE_TO_FRESH) 
                    { 
                        state = LOADING; 
                        changeHeadViewState(); 

                        //刷新界面 
                        onRefresh(); 
                    } 
                } 
                isRecorded = false; 
                break; 
        } 
        return super.onTouchEvent(ev); 
    } 

    /** 
     * 刷新界面的数据 
     * 
     * @see onRefresh 
     */ 
    private void onRefresh() 
    { 
        if(null != onRefreshListener) 
        { 
            onRefreshListener.onRefresh(); 
        } 
    } 

    /** 
     * 界面刷新结束 
     * 
     * @see complete 
     */ 
    public void complete() 
    { 
        state = DONE; 
        changeHeadViewState(); 
    } 

    /** 
     * 根据状态修改headView 
     * 
     * @see changeHeadViewState 
     */ 
    private void changeHeadViewState() 
    { 
        switch(state) 
        { 
            //箭头向上 
            case RELEATSE_TO_FRESH: 
                arrowImageView.setVisibility(View.VISIBLE); 
                progressBar.setVisibility(View.GONE); 
                tipsTextView.setVisibility(View.VISIBLE); 
                arrowImageView.clearAnimation(); 
                arrowImageView.startAnimation(toupAnimation); 
                Log.e(VIEW_LOG_TAG, "RELEATSE_TO_FRESH"); 
                tipsTextView.setText("松开刷新"); 
                break; 

           //箭头向下    
            case PULL_TO_REFRESH: 
                arrowImageView.setVisibility(View.VISIBLE); 
                progressBar.setVisibility(View.GONE); 
                tipsTextView.setVisibility(View.VISIBLE); 
                if(isback) 
                { 
                    Log.e(VIEW_LOG_TAG, "PULL_TO_REFRESH"); 
                    arrowImageView.clearAnimation(); 
                    arrowImageView.startAnimation(todownAnimation); 
                    isback = false; 
                } 
                tipsTextView.setText("下拉刷新"); 
                break; 

            case DONE: 
                headView.setPadding(0, -headContextHeight, 0, 0); 
                arrowImageView.setVisibility(View.VISIBLE); 
                progressBar.setVisibility(View.GONE); 
                tipsTextView.setVisibility(View.VISIBLE); 
                arrowImageView.clearAnimation(); 
                tipsTextView.setText("下拉刷新"); 
                break; 

            //正在现在插件    
            case LOADING: 
                headView.setPadding(0,0, 0, 0); 
                arrowImageView.setVisibility(View.GONE); 
                progressBar.setVisibility(View.VISIBLE); 
                tipsTextView.setVisibility(View.VISIBLE); 
                arrowImageView.clearAnimation(); 
                tipsTextView.setText("正在刷新"); 
                break; 
            default: 
                break; 
        } 
    } 


    /** 
     * 重新设置headView的大小 
     * 
     * @see resetHeadView 
     */ 
    private void resetHeadView() 
    { 
        ViewGroup.LayoutParams layoutParams = headView.getLayoutParams(); 
        if(null == layoutParams) 
        { 
            layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT); 
        } 
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, layoutParams.width); 
        int tempHeight = layoutParams.height; 
        int childHeightSpec=0; 
        if(tempHeight>0) 
        { 
            childHeightSpec=MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY); 
        } 
        else 
        { 
            childHeightSpec=MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.UNSPECIFIED); 
        } 
       headView.measure(childWidthSpec, childHeightSpec); 
    } 



    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) 
    { 
    } 

    /** 
     * listView滑动的时候获取第一个显示的item 
     */ 
    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) 
    { 
        fistVisibleItem = firstVisibleItem; 
    } 

    public void setOnRefreshListener(OnRefreshListener onRefreshListener) 
    { 
        this.onRefreshListener = onRefreshListener; 
    } 
}





上传一张显示的箭头的图片,这是重其它地方搞来的