继续上一篇的话题:
手指松开的时候,进行的更严谨的逻辑,避免了endHeight在任意状态都被调用。
状态修改进行了重构。
源码下载: https://github.com/q742972035/pullrefreshlvOnlyOneHandler
前篇:自定义(扩展性能强!)的下拉刷新和上拉加载控件
上一篇结束时提到,功能有些不好的地方,在此篇进行改进。
因为上一篇说了细节,所以这篇着重说修改过的地方。
/**
* 可见item高度
*/
private int visiableItemHeights;
public void initHeight() {
hasScroll = false;
visiableItemHeights = 0;
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
for (int i = 0; i < getChildCount(); i++) {
visiableItemHeights += getChildAt(i).getHeight();
}
}
});
}
在一开始初始化的时候,调用这个方法,目的是为了得到item的总高有没超过屏幕,没有的话,上拉加载就不会出现。
/**
* 关闭下拉刷新
*/
private void closeRefreshing() {
isLoading = false;
setSelection(1);
initHeight();
if (mState != PULL_REFRESH)
setState(PULL_REFRESH);
headerView.setPadding(0, headerHeight, 0, 0);
if (mCallback != null)
mCallback.stopRefresh();
}
重新构造该方法,使其更严谨,多了一处刷新完毕之后,直接显示第一项
(0是头布局)
case MotionEvent.ACTION_UP:
isUp = true;
// 最终位置
endHeight = -1;
if (mState == PULL_REFRESH)
endHeight = headerHeight;
else if (mState == LOOSEN_REFRESH)
endHeight = 0;
if (endHeight != -1) {
valueAnimator = ValueAnimator.ofInt(headerView.getPaddingTop(), endHeight);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int padding = (int) animation.getAnimatedValue();
lastPadding = padding;
float percent = (padding + Math.abs(headerHeight)) * 1.0f / Math.abs(headerHeight);
if (mCallback != null) {
mCallback.drag(percent, padding - lastPadding);
}
if (padding < 0) {
if (mCallback != null)
mCallback.dragToLoosen(percent, padding - lastPadding);
}
headerView.setPadding(0, padding, 0, 0);
}
});
valueAnimator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
if (endHeight == 0) {
setState(REFRESHING);
} else if (endHeight == headerHeight)
setState(PULL_REFRESH);
}
});
valueAnimator.setDuration(mDuration);
valueAnimator.start();
}
break;
}
手指松开的时候,进行的更严谨的逻辑,避免了endHeight在任意状态都被调用。
private void setState(int state) {
if (isLoading)
state = LOADING;
switch (state) {
// 下拉刷新状态
case PULL_REFRESH:
if (mState != PULL_REFRESH && headerView != null) {
mState = PULL_REFRESH;
if (mCallback != null)
mCallback.toRullRefresh();
}
break;
// 松开刷新状态
case LOOSEN_REFRESH:
if (mState != LOOSEN_REFRESH && headerView != null) {
mState = LOOSEN_REFRESH;
if (mCallback != null)
mCallback.toLoosenRefresh();
}
break;
// 正在刷新状态
case REFRESHING:
if (mState != REFRESHING && headerView != null) {
mState = REFRESHING;
if (mCallback != null)
mCallback.toRefreshing();
}
break;
case LOADING:
if (!isLoading) {
footerView.setPadding(0, 0, 0, 0);
isLoading = true;
if (mState != LOADING && footerView != null) {
mState = LOADING;
if (mCallback != null)
mCallback.toLoading();
}
}
break;
default:
break;
}
}
状态修改进行了重构。
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (headerView != null) {
if (getFirstVisiblePosition() >= 1 && scrollState == OnScrollListener.SCROLL_STATE_FLING) {
headerView.setPadding(0, headerHeight, 0, 0);
if (mState == REFRESHING)
headerView.setPadding(0, 0, 0, 0);
}
}
if (scrollState == SCROLL_STATE_FLING || scrollState == SCROLL_STATE_TOUCH_SCROLL) {
if (mCallback!=null)
mCallback.scroll();
}
if (footerView == null || !hasScroll || visiableItemHeights < getHeight())
return;
if (getLastVisiblePosition() == getCount() - 1 && mState != REFRESHING && scrollState==SCROLL_STATE_IDLE) {
if ( !isLoading) {
setState(LOADING);
setSelection(getCount());
}
}
}
滑动监听的逻辑都写在了一块,为了根据滑动状态做不同的处理。
所以,另外一个滑动监听的方法就没东西了,是一个空方法。
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
源码下载: https://github.com/q742972035/pullrefreshlvOnlyOneHandler