ListView实现下拉刷新(一)

来源:互联网 发布:做视频短片的软件 编辑:程序博客网 时间:2024/05/17 05:55
package com.hdmes.handingv2017.MyActivitys;import android.content.Context;import android.text.format.Time;import android.view.animation.RotateAnimation;import android.widget.AbsListView.OnScrollListener;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;import com.hdmes.handingv2017.R;/** * Created by Administrator on 2017/10/30. */public class RefreshListView extends ListView implements OnScrollListener {    View header;// 顶部提示View    int headerHeight;//header的高度    int firstVisibleItem;//当前界面第一个可见的item的位置    boolean isFlag;//标志,是在当前显示的listView是在listView最顶端时按下额    int startY;//用户按下的Y值    int state;//当前状态    final int NONE = 0;//正常状态    final int PULL = 1;//提示下拉状态    final int RELEASE = 2;//提示释放状态    final int REFRESH = 3;//提示正在刷新状态    private int scrollState = 1;//滚动状态为 1    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {        // TODO Auto-generated method stub        this.scrollState = scrollState;    }    @Override    public void onScroll(AbsListView view, int firstVisibleItem,                         int visibleItemCount, int totalItemCount) {        // TODO Auto-generated method stub        this.firstVisibleItem = firstVisibleItem;    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        // TODO Auto-generated method stub        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                if (firstVisibleItem == 0) {                    isFlag = true;//ListView最顶端按下,标志值设为真                    startY = (int) ev.getY();                }                break;            case MotionEvent.ACTION_MOVE:                onMove(ev);                break;            case MotionEvent.ACTION_UP:                if (state == RELEASE) {                    state = REFRESH;                    //加载数据                    refreshViewByState();                    iRefreshlistener.onRefresh();//刷新状态                } else if (state == PULL) {                    state = NONE;                    isFlag = false;                    refreshViewByState();                }                break;        }        return super.onTouchEvent(ev);    }    //    private void onMove(MotionEvent ev) {        //如果不是最顶端按下,则直接返回        if (!isFlag) {            return;        }        int currentY = (int) ev.getY();//当前的Y值        int space = currentY - startY;//用户向下拉的距离        int topPadding = space - headerHeight;//顶部提示View距顶部的距离值        switch (state) {            //正常状态            case NONE:                if (space > 0) {                    state = PULL;//下拉的距离大于0,则将状态改为PULL(提示下拉更新)                    refreshViewByState();//根据状态的不同更新View                }                break;            case PULL:                topPadding(topPadding);                if (space > headerHeight + 30//下拉的距离大于header的高度加30且用户滚动屏幕,手指仍在屏幕上                        && scrollState == SCROLL_STATE_TOUCH_SCROLL) {                    state = RELEASE;//将状态改为RELEASE(提示松开更新)                    refreshViewByState();                }                break;            case RELEASE:                topPadding(topPadding);                if (space < headerHeight + 30) {//用户下拉的距离不够                    state = PULL;         //将状态改为PULL                    refreshViewByState();                } else if (space <= 0) {  //用户下拉的距离为非正值                    state = NONE;    //将状态改为NONE                    isFlag = false;  //标志改为false                    refreshViewByState();                }                break;        }    }    //    /**     * 根据当前状态state,改变界面显示     * state:     * NONE:无操作     * PULL:下拉可以刷新     * RELEASE:松开可以刷新     * REFREASH:正在刷新     */    private void refreshViewByState() {        //提示        TextView tips = (TextView) header.findViewById(R.id.tips);        //箭头        ImageView arrow = (ImageView) header.findViewById(R.id.arrow);        //进度条        ProgressBar progress = (ProgressBar) header.findViewById(R.id.progress);        //箭头的动画效果1,由0度转向180度,即箭头由朝下转为朝上        RotateAnimation animation1 = new RotateAnimation(0, 180,                RotateAnimation.RELATIVE_TO_SELF, 0.5f,                RotateAnimation.RELATIVE_TO_SELF, 0.5f);        animation1.setDuration(500);        animation1.setFillAfter(true);        //箭头的动画效果2,由180度转向0度,即箭头由朝上转为朝下        RotateAnimation animation2 = new RotateAnimation(180, 0,                RotateAnimation.RELATIVE_TO_SELF, 0.5f,                RotateAnimation.RELATIVE_TO_SELF, 0.5f);        animation2.setDuration(500);        animation2.setFillAfter(true);        switch (state) {            case NONE:                     //正常状态                arrow.clearAnimation();    //清除箭头动画效果                topPadding(-headerHeight); //设置header距离顶部的距离                break;            case PULL:                                //下拉状态                arrow.setVisibility(View.VISIBLE);    //箭头设为可见                progress.setVisibility(View.GONE);    //进度条设为不可见                tips.setText("下拉刷新");           //提示文字设为"下拉可以刷新"                arrow.clearAnimation();               //清除之前的动画效果,并将其设置为动画效果2                arrow.setAnimation(animation2);                break;            case RELEASE:                            //下拉状态                arrow.setVisibility(View.VISIBLE);   //箭头设为可见                progress.setVisibility(View.GONE);   //进度条设为不可见                tips.setText("释放立即刷新");          //提示文字设为"松开可以刷新"                arrow.clearAnimation();              //清除之前的动画效果,并将其设置为动画效果2                arrow.setAnimation(animation1);                break;            case REFRESH:                             //更新状态                topPadding(50);                       //距离顶部的距离设置为50                arrow.setVisibility(View.GONE);       //箭头设为不可见                progress.setVisibility(View.VISIBLE); //进度条设为可见                tips.setText("正在刷新...");            //提示文字设为""正在刷新..."                arrow.clearAnimation();                //清除动画效果                break;        }    }    //    IRefreshListener iRefreshlistener;//刷新数据的接口    // ...    public void setInterface(IRefreshListener listener) {        this.iRefreshlistener = listener;    }    /**     * 刷新数据接口     *     * @author fu     */    public interface IRefreshListener {        public void onRefresh();    }    //    public void refreshComplete() {        state = NONE;   //状态设为正常状态        isFlag = false; //标志设为false        refreshViewByState();        //设置提示更新时间间隔        Time t = new Time();        t.setToNow();        //time = t.hour*60+t.minute-updateTime;        //updateTime = t.hour*60+t.minute;        TextView lastUpdateTime = (TextView) findViewById(R.id.time);        lastUpdateTime.setText("time" + "分钟前更新");    }    //    public RefreshListView(Context context) {        super(context);        initView(context);    }    public RefreshListView(Context context, AttributeSet attrs) {        super(context, attrs);        initView(context);    }    public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView(context);    }    private void initView(Context context) {        //LayoutInflater作用是加载布局        LayoutInflater inflater = LayoutInflater.from(context);        header = inflater.inflate(R.layout.header_layout, null);        measureView(header);        headerHeight = header.getMeasuredHeight();        topPadding(-headerHeight);        this.addHeaderView(header);    }    /**     * 设置顶部布局的上边距     *     * @param topPadding     */    private void topPadding(int topPadding) {        //设置顶部提示的边距        //除了顶部用参数值topPadding外,其他三个用header默认的值        header.setPadding(header.getPaddingLeft(), topPadding,                header.getPaddingRight(), header.getPaddingBottom());        //使header无效,将来调用onDraw()重绘View        header.invalidate();    }    /**     * 通知父布局,占用的宽和高     */    private void measureView(View view) {        //LayoutParams are used by views to tell their parents        //how they want to be laid out.        //LayoutParams被view用来告诉它们的父布局它们应该被怎样安排        ViewGroup.LayoutParams p = view.getLayoutParams();        if (p == null) {            //两个参数:width,height            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,                    ViewGroup.LayoutParams.WRAP_CONTENT);        }        //getChildMeasureSpec:获取子View的widthMeasureSpec、heightMeasureSpec值        int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);        int height;        int tempHeight = p.height;        if (tempHeight > 0) {            height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);        } else {            height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);        }        view.measure(width, height);    }}
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:paddingBottom="10dip"        android:paddingTop="10dip">        <LinearLayout            android:id="@+id/layout"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:gravity="center"            android:orientation="vertical">            <!-- 提示文字 -->            <TextView                android:id="@+id/tips"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="下拉可以刷新"                android:textColor="#212020" />            <!-- 距上次更新至今的时间 -->            <TextView                android:id="@+id/time"                android:layout_width="wrap_content"                android:layout_height="wrap_content" />        </LinearLayout>        <!-- 箭头 -->        <ImageView            android:id="@+id/arrow"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_toLeftOf="@id/layout"            android:background="@color/colorTextGray"            android:src="@android:drawable/stat_sys_download_done" />        <!-- 更新进度条 -->        <ProgressBar            android:id="@+id/progress"            style="?android:attr/progressBarStyleSmall"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_toLeftOf="@id/layout"            android:visibility="gone" />    </RelativeLayout></LinearLayout>

原创粉丝点击