自定义listview的下拉刷新和上拉加载

来源:互联网 发布:java ping 域名是否通 编辑:程序博客网 时间:2024/05/17 02:44
第一次写博客,有点小激动,以后会坚持下来,记录学习的生涯
经常会用到listview的下拉刷新和上拉加载,虽然个github上有很多开源的框架,总感觉用着不是很理解,决定自己写一写。
效果图:

自定义listview,添加headerview和footerview,监听滚动事件;

MyListView.java

import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.AbsListView;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;public class MyListView extends ListView implements AbsListView.OnScrollListener {    public int height;    private int offsetheight;//记录listview下拉偏移量    private ImageView arrow;    private TextView dateText;    private TextView tipsText;    private View headerView;//listview头布局    public View footView;//listview脚布局    private int totalItemCount;//全部的列表项    private int startY;//listview开始下拉的位置    private int firstVisibleItem;//记录第一个下拉的项    private int lastVisibleItem;    private int STATE;//记录当前状态    private boolean isFromBegin;//记录是否从头开始下拉    private final int NONE = 0;//listview处于静态    private final int PULL = 1;//listview处于下拉状态    private final int RELESE = 2;//listview处于松开刷新的状态    private final int RELESING = 3;//listview处于正在刷新状态    private LoadListener loadListener;//底部加载监听    public ProgressBar progressBar;    private RefreshListener refreshListener;//头部刷新监听    public void setRefreshListener(RefreshListener refreshListener) {        this.refreshListener = refreshListener;    }    public void setLoadListener(LoadListener loadListener) {        this.loadListener = loadListener;    }    public MyListView(Context context) {        super(context);        init(context);    }    public MyListView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    /**     * 初始化组件,添加headerView和footView     */    public void init(Context context) {        headerView = LayoutInflater.from(context).inflate(R.layout.headerview, null);        footView = LayoutInflater.from(context).inflate(R.layout.footview, null);        arrow = (ImageView) headerView.findViewById(R.id.arrow);        dateText = (TextView) headerView.findViewById(R.id.date);        tipsText = (TextView) headerView.findViewById(R.id.tips);        progressBar = (ProgressBar) headerView.findViewById(R.id.progressbar);        notifyView(headerView);        height = headerView.getMeasuredHeight();        setPadding(-height);        footView.setVisibility(INVISIBLE);        this.addHeaderView(headerView);//添加头布局        this.addFooterView(footView);//添加脚布局        this.setOnScrollListener(this);        this.setVerticalScrollBarEnabled(false);//隐藏滚动条    }    /**     * 通知父布局测量子布局的尺寸     */    public void notifyView(View view) {        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();        if (layoutParams == null) {            layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);        }        int with = ViewGroup.getChildMeasureSpec(0, 0, view.getWidth());        int height;        int viewheight = view.getHeight();        if (viewheight > 0) {            MeasureSpec.makeMeasureSpec(viewheight, MeasureSpec.EXACTLY);        } else {            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);        }        view.measure(with, viewheight);    }    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {        //判断是否到达列表的最底部和加载数据        if (this.lastVisibleItem == this.totalItemCount) {            footView.setVisibility(VISIBLE);            loadListener.getLoadData();        }    }    @Override    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {        this.firstVisibleItem = firstVisibleItem;        this.lastVisibleItem = firstVisibleItem + visibleItemCount;        this.totalItemCount = totalItemCount;    }    /**     * 监听listview的touch事件     */    @Override    public boolean onTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                if (firstVisibleItem == 0) {                    STATE = NONE;                    isFromBegin = true;                    startY = (int) ev.getY();                }                break;            case MotionEvent.ACTION_MOVE:                move(ev);                break;            case MotionEvent.ACTION_UP:                if (STATE == RELESE) {                    STATE = RELESING;                    ChangeViewFromState(STATE);                } else if (STATE == PULL) {                    STATE = NONE;                    ChangeViewFromState(STATE);                }                break;            default:                break;        }        return super.onTouchEvent(ev);    }    /**     * @param ev     * listview滑动状态的处理,分发处理listview下拉达到的状态     */    public void move(MotionEvent ev) {        if (!isFromBegin) {            return;        }        offsetheight = (int) ev.getY() - startY;        switch (STATE) {            case NONE:                setPadding(offsetheight);                if (offsetheight > 0) {                    STATE = PULL;                    ChangeViewFromState(STATE);                }                break;            case PULL:                setPadding(offsetheight);                if (offsetheight >= height + 60) {                    STATE = RELESE;                    ChangeViewFromState(STATE);                }                break;            case RELESE:                setPadding(offsetheight);                if (offsetheight < height + 60) {                    STATE = PULL;                    ChangeViewFromState(STATE);                }                break;        }    }    /**     * 设置headerview的padding     * @param offsetHeight     */    public void setPadding(int offsetHeight) {        headerView.setPadding(headerView.getPaddingLeft(), -height + offsetHeight, headerView.getPaddingLeft(), headerView.getPaddingBottom());        headerView.invalidate();    }    /**     * 根据当前的状态改变headerview的view     * @param state     */    public void ChangeViewFromState(int state) {        RotateAnimation animation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);        animation.setDuration(500);        animation.setFillAfter(true);        RotateAnimation animation1 = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);        animation1.setDuration(500);        animation1.setFillAfter(true);        switch (state) {            case NONE:                arrow.clearAnimation();                setPadding(-height);                tipsText.setText("下拉刷新");                break;            case PULL:                arrow.clearAnimation();                //arrow.setAnimation(animation1);                tipsText.setText("下拉刷新");                arrow.setVisibility(VISIBLE);                progressBar.setVisibility(GONE);                break;            case RELESE:                arrow.clearAnimation();                arrow.setAnimation(animation);                tipsText.setText("松开刷新");                break;            case RELESING:                setPadding(height);                arrow.clearAnimation();                tipsText.setText("正在刷新...");                arrow.setVisibility(GONE);                progressBar.setVisibility(VISIBLE);                refreshListener.getRefreshData();                break;        }    }    /**     * listview的下拉刷新数据接口     */    public interface RefreshListener {        public void getRefreshData();    }    /**     * listview的上拉加载数据接口     */    public interface LoadListener {        public void getLoadData();    }    /**     * 更新headerview刷新的时间     */    public void refreshTime() {        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm", Locale.CHINA);        Date date = new Date(System.currentTimeMillis());        String datatime = simpleDateFormat.format(date);        dateText.setText(datatime);    }}

其它部分比较简单,就不展示出来了

0 0
原创粉丝点击