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

第一次写博客,有点小激动,以后会坚持下来,记录学习的生涯
经常会用到listview的下拉刷新和上拉加载,虽然个github上有很多开源的框架,总感觉用着不是很理解,决定自己写一写。
效果图:

自定义listview的下拉刷新和上拉加载_第1张图片

自定义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);
    }
}

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

你可能感兴趣的:(ListView)