Android中实现Listview下拉刷新的核心代码解析

private void initHeaderView(){  //初始化headerView

mHeaderView = View.inflate(getContext(), R.layout.refresh_header, null);//获得headerView
this.addHeaderView(mHeaderView);//将headerView加在listView的上面

tvTitle = (TextView) mHeaderView.findViewById(R.id.tv_title);//刷新的提示文字
tvTime = (TextView) mHeaderView.findViewById(R.id.tv_time);//刷新的时间显示
ivArrow = (ImageView) mHeaderView.findViewById(R.id.iv_arr);//下拉箭头
pbProgress = (ProgressBar) mHeaderView.findViewById(R.id.pb_progress);//旋转的进度条
mHeaderView.measure(0, 0);
mHeaderViewHeight = mHeaderView.getMeasuredHeight();//测得headerView的高度

mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);// 隐藏头布局
initArrowAnim();// 初始化箭头动画

}
@Override
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN://手指按在屏幕上时
        startY = (int) ev.getRawY();//获取手指所按的Y坐标
        break;
    case MotionEvent.ACTION_MOVE://手指在屏幕上滑动
        if (startY == -1) {// 确保startY有效
            startY = (int) ev.getRawY();
        }

        if (mCurrrentState == STATE_REFRESHING) {// 正在刷新时不做处理
            break;
        }

        int endY = (int) ev.getRawY();//时刻获取手指滑动时的坐标
        int dy = endY - startY;// 移动偏移量

        if (dy > 0 && getFirstVisiblePosition() == 0) {// 只有下拉并且当前是第一个item,才允许下拉
    /* 计算padding,最开始时padding为负的mHeaderViewHeight,
    此时HeaderView隐藏在Listview上方,随着手指下滑,移动偏移量dy增大,HeaderView一点点被拖出来显示在屏幕上,
    当dy正好等于mHeaderViewHeight时,padding为0,也就说此时HeaderView正好完全在屏幕上方显示出来*/
            int padding = dy - mHeaderViewHeight;
            mHeaderView.setPadding(0, padding, 0, 0);// 设置当前padding

            if (padding > 0 && mCurrrentState != STATE_RELEASE_REFRESH) {
            /* 当padding大于0时,说明此时HeaderView已经完全展示出来,可以松开手指进行刷新了,
            如果此时状态不为松开刷新状态则将状态改为松开刷新,提示用户。*/
                mCurrrentState = STATE_RELEASE_REFRESH;
                refreshState();
            } else if (padding < 0 && mCurrrentState != STATE_PULL_REFRESH) {
    /* 如果padding小于0,这说明HeaderView并没有完全展示出来,
    用户可以继续下拉,此时如果状态不为下拉刷新则将状态改为下拉刷新提示用户。*/
                mCurrrentState = STATE_PULL_REFRESH;
                refreshState();
            }

            return true;
        }

        break;
    case MotionEvent.ACTION_UP://手指抬起
        startY = -1;// 重置

        if (mCurrrentState == STATE_RELEASE_REFRESH){//如果此时状态为松开刷新
            mCurrrentState = STATE_REFRESHING;//将状态改为正在刷新 正在刷新
            mHeaderView.setPadding(0, 0, 0, 0);// 显示HeaderView
            refreshState();
        } else if (mCurrrentState == STATE_PULL_REFRESH) {//如果此时状态为下拉刷新,说明HeaderView没有
        被完全显示出来,按照实际,只有完全拖拽显示出来才进行刷新
            mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);// 将HeaderView收缩回去隐藏起来,
        }

        break;

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



     /*
      * 刷新下拉控件的布局
     */
    private void refreshState() {
    switch (mCurrrentState) {
    case STATE_PULL_REFRESH:
        tvTitle.setText("下拉刷新");//更改状态显示文字
        ivArrow.setVisibility(View.VISIBLE);//设置下拉箭头可见
        pbProgress.setVisibility(View.INVISIBLE);//进度条不可见
        ivArrow.startAnimation(animDown);开启动画
        break;
    case STATE_RELEASE_REFRESH:
        tvTitle.setText("松开刷新");
        ivArrow.setVisibility(View.VISIBLE);
        pbProgress.setVisibility(View.INVISIBLE);
        ivArrow.startAnimation(animUp);
        break;
    case STATE_REFRESHING:
        tvTitle.setText("正在刷新...");
        ivArrow.clearAnimation();// 必须先清除动画,才能隐藏
        ivArrow.setVisibility(View.INVISIBLE);
        pbProgress.setVisibility(View.VISIBLE);

        if (mListener != null) {
            mListener.onRefresh();
        }
        break;

    default:
        break;
    }
}



    /**
     * 初始化箭头动画
     */
    private void initArrowAnim() {
    // 箭头向上动画
    animUp = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    animUp.setDuration(200);
    animUp.setFillAfter(true);

    // 箭头向下动画
    animDown = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    animDown.setDuration(200);
    animDown.setFillAfter(true);

}
文章目录
|