RefreshListView 下拉刷新和上拉加载

public class RefreshListView extends ListView {

    private ImageView iv_red_arrow;
    private ProgressBar pb_status;
    private TextView tv_status;
    private TextView tv_time;

    /**
     * 整个header(下拉刷新控件和顶部轮播图)
     */
    private LinearLayout headerView;
    /**
     * 下拉刷新控件
     */
    private View ll_pull_dwon;
    private int headViewHeight;
    private View topNewsView; //顶部轮播图
    private int listViewOnScreemY=-1;  //listview在Y轴的坐标

    /**
     * 下拉刷新状态
     **/
    private static final int PULL_DOWN_REFRESH = 1;


    /**
     * 手松刷新状态
     **/
    private static final int RELEASE_REFRESH = 2;


    /**
     * 正在刷新状态
     **/
    private static final int REFRESHING = 3;

    /**
     * 当前状态
     */
    private int currentState = PULL_DOWN_REFRESH;
    private Animation upAnimation,downAnimation;
    private View footView;
    private int footViewHight;
    private boolean isLoadMore=false;

    public RefreshListView(Context context) {
        this(context,null);
    }

    public RefreshListView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initHeaderView(context);
        initAnimation();
        initFooterView(context);

        setOnScrollListener(new MyOnScrollListener());
    }

    class MyOnScrollListener implements OnScrollListener{

        @Override
        public void onScrollStateChanged(AbsListView absListView, int i) {
            //静止或者滚动
            if (i == OnScrollListener.SCROLL_STATE_IDLE || i == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                if (getLastVisiblePosition() == getAdapter().getCount() - 1) {
                    footView.setPadding(10,10,10,10);
                    isLoadMore=true;

                    if (mOnRefreshLisener != null) {
                        mOnRefreshLisener.onLoadMore();
                    }
                }
            }
        }

        @Override
        public void onScroll(AbsListView absListView, int i, int i1, int i2) {

        }
    }

    private void initFooterView(Context context) {
        footView = View.inflate(context, R.layout.refresh_footer, null);
        footView.measure(0,0);
        footViewHight=footView.getMeasuredHeight();
        footView.setPadding(0,-footViewHight,0,0);
        RefreshListView.this.addFooterView(footView);

    }

    private void initAnimation() {
        upAnimation=new RotateAnimation(0,-180,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        upAnimation.setDuration(500);
        upAnimation.setFillAfter(true);

        downAnimation=new RotateAnimation(-180,-360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        downAnimation.setDuration(500);
        downAnimation.setFillAfter(true);
    }

    private void initHeaderView(Context context) {
        headerView= (LinearLayout) View.inflate(context, R.layout.header_view,null);

        ll_pull_dwon = headerView.findViewById(R.id.ll_pull_donw);
        iv_red_arrow = (ImageView) headerView.findViewById(R.id.iv_red_arrow);
        pb_status = (ProgressBar) headerView.findViewById(R.id.pb_status);
        tv_status = (TextView) headerView.findViewById(R.id.tv_status);
        tv_time = (TextView) headerView.findViewById(R.id.tv_time);

        ll_pull_dwon.measure(0,0);
        headViewHeight=ll_pull_dwon.getMeasuredHeight();
        ll_pull_dwon.setPadding(0,-headViewHeight,0,0);

        RefreshListView.this.addHeaderView(headerView);
    }
    float startY=0;

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                startY = ev.getY();

                break;
            case MotionEvent.ACTION_MOVE:
                if (startY==0){
                    startY = ev.getY();
                }
                //判断是下拉还是上拉
                Boolean isDisplayTopNews=isTopNewsDisplay();
                if (!isDisplayTopNews){  //不是完全显示,则不需处理下拉刷新逻辑
                    break;
                }

                float endY=ev.getY();
                float distanceY=endY-startY;
                if (distanceY>0){
                    int paddingTop= (int) (-headViewHeight+distanceY);
                    if (paddingTop < 0 && currentState != PULL_DOWN_REFRESH) {
                        //下拉刷新
                        currentState = PULL_DOWN_REFRESH;
                        refreshStatus();
                        //更新状态
                    } else if (paddingTop > 0 && currentState != RELEASE_REFRESH) {
                        //手势刷新
                        currentState = RELEASE_REFRESH;
                        //更新状态
                        refreshStatus();
                    }

                    ll_pull_dwon.setPadding(0,paddingTop,0,0);
                }
                break;
            case MotionEvent.ACTION_UP:
                startY=0;
                if (currentState == PULL_DOWN_REFRESH) {
                    //View.setPadding(0,-控件高,0,0);//完成隐藏
                    ll_pull_dwon.setPadding(0, -headViewHeight, 0, 0);
                } else if (currentState == RELEASE_REFRESH) {

                    currentState = REFRESHING;

                    //View.setPadding(0,0,0,0);//完成显示
                    ll_pull_dwon.setPadding(0, 0, 0, 0);
                    //状态要更新
                    refreshStatus();

                    if (mOnRefreshLisener!=null){
                        mOnRefreshLisener.pullDownRefresh();
                    }

                    }
                break;
            default:
                break;
        }
        return super.onTouchEvent(ev);
    }

    private void refreshStatus() {
       switch (currentState){
           case PULL_DOWN_REFRESH:
               tv_status.setText("下拉刷新...");
               iv_red_arrow.startAnimation(downAnimation);
               break;
           case RELEASE_REFRESH:
               tv_status.setText("手松刷新...");
               iv_red_arrow.startAnimation(upAnimation);
               break;
           case REFRESHING:
               tv_status.setText("正在刷新...");
               pb_status.setVisibility(VISIBLE);
               iv_red_arrow.setVisibility(GONE);
               iv_red_arrow.clearAnimation();

               break;
       }
    }

    /**
     * 判断顶部轮播图是否完全显示
     * @return
     */
    private Boolean isTopNewsDisplay() {
        if (topNewsView != null) {
            int[] location=new int[2];
            if (listViewOnScreemY==-1){
                this.getLocationOnScreen(location);
                listViewOnScreemY=location[1];
            }

            topNewsView.getLocationOnScreen(location);
            int topNewsViewOnScreemY=location[1];
            if (topNewsViewOnScreemY>=listViewOnScreemY){
                return true;
            }else{
                return false;
            }
        }else{
            return true;
        }

    }

    public void addTopNewView(View topNewsView) {
        if (topNewsView!=null&&headerView!=null){
            this.topNewsView=topNewsView;
            headerView.addView(topNewsView); //代码添加顶部轮播图
        }
    }

    public void onRefreshFinish(boolean success) {
        if(isLoadMore){
            //加载更多
            isLoadMore = false;
            footView.setPadding(0,-footViewHight,0,0);
        }else{
            //下拉刷新
            iv_red_arrow.clearAnimation();
            iv_red_arrow.setVisibility(VISIBLE);
            pb_status.setVisibility(GONE);
            tv_status.setText("下拉刷新...");
            ll_pull_dwon.setPadding(0, -headViewHeight, 0, 0);
            currentState = PULL_DOWN_REFRESH;
            if (success) {
                //更新时间
                tv_time.setText("更新时间:" + getSystemTime());
            }
        }
    }

    private String getSystemTime() {
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        return format.format(new Date());
    }

    /**
     * 视图刷新监听接口
     */
    public interface onRefreshLisener{

        public void pullDownRefresh(); //调用接口时执行此方法
        public void onLoadMore();
    }

    private onRefreshLisener mOnRefreshLisener;

    /**
     * 添加视图刷新的监听
     * by ppa
     * @param lisener
     */
    public void setmOnRefreshLisener(onRefreshLisener lisener){
        this.mOnRefreshLisener=lisener;
    }
}

自定义下拉刷新
1.自定义一个类RefreshListView继承ListView,重写构造方法 在构造方法里面初始化下拉刷新的布局

2.写下拉刷新的布局refresh_header.xml 自定义ProgressBar,把控件初始化

3.实现手指移动下拉刷新控件 下拉刷新控件隐藏和显示的原理 View.setPadding(0,-控件高,0,0);//完成隐藏 View.setPadding(0,0,0,0);//完成显示 View.setPadding(0,控件高,0,0);//两倍完全显示

4.重写控件的onTouchEvent() a,在down的时候记录起始坐标 startY

b,在move float endY ;

float distanceY = endY - startY; if(distanceY >0){

int paddingTop = - 控件的高 + distanceY;
View.setPadding(0,paddingTop,0,0)//动态显示下拉刷新控件
}

c,在up的时候,要重新赋值startY = 0;

5.解决下拉刷新的bug,判断顶部轮播图是否完全显示 如何判断顶部轮播图是否完全显示呢 当ListView在Y轴的坐标小于或者等于顶部轮播图部分在Y轴的坐标的时候

6.下拉刷新状态和动画

/* 下拉刷新状态 */ private static final int pull_down_refresh = 1;

/* 手松刷新状态 */ private static final int release_refresh = 2;

/**
正在刷新状态 **/ private static final int refreshing = 3;

private int currentState = pull_down_refresh;

在move float endY ;

float distanceY = endY - startY; if(distanceY >0){

int paddingTop = - 控件的高 + distanceY;
if(paddingTop < 0 && currentState != pull_down_refresh){
//下拉刷新
currentState = pull_down_refresh;
//更新状态
}else if(paddingTop >0 && currentState != release_refresh){
//手势刷新
currentState = release_refresh;
//更新状态
}

View.setPadding(0,paddingTop,0,0)//动态显示下拉刷新控件
}

在up

if(currentState == pull_down_refresh){ //View.setPadding(0,-控件高,0,0);//完成隐藏 }else if(currentState ==release_refresh){

currentState = refreshing;
//状态要更新
//View.setPadding(0,0,0,0);//完成显示
//回调接口
}

7.定义下拉刷新接口

/**

监听视图刷新监听者 / public interface OnRefreshListener{ / 当下拉刷新的时候回调这个方法 */ public void onPullDownlRefresh(); }

private OnRefreshListener mOnRefreshListener;

/* 设置视图刷新的监听 / public void setOnRefreshListener(OnRefreshListener l){ this.mOnRefreshListener = l; }

在up

if(currentState == pull_down_refresh){ //View.setPadding(0,-控件高,0,0);//完成隐藏 }else if(currentState ==release_refresh){

currentState = refreshing;
//状态要更新
//View.setPadding(0,0,0,0);//完成显示
//回调接口
if(mOnRefreshListener != null){
mOnRefreshListener.onPullDownlRefresh();
}
}

上拉刷新(加载更多)

1.在构造方法中初始化

2.监听ListVivew滑到最后一条

3.写加载更多的接口方法

/**

监听视图刷新监听者 / public interface OnRefreshListener{ / 当下拉刷新的时候回调这个方法 */ public void onPullDownlRefresh();

/**
当加载更多的时候回调这方法
*/
public void onLoadMore();
}

4.调用接口 //回调接口 if(mOnRefreshListener != null){ mOnRefreshListener.onLoadMore(); }

5.在TabDetailPager,对接口实现,加载更多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值