The library Overscrollscale modifies the listview
overscroll and makes it bounce at edges. The list is also scaled when user over scrolls it and is scaled back to normal size after the user releases the touch.
Code for scaling the listview
:
private static void setListScale(final ListViewExt listView, Canvas canvas, int offset, boolean isTween) {
if (offset == 0) {
canvas.scale(1, listView.getScaleY(), 0, listView.mLastPivotY);
listView.invalidate();
return;
}
double scaleRatio = Math.min(Math.max(0.0d, (Math.sqrt((double) Math.abs(offset)) * 3.0d) * 0.001d), 0.1d);
if (listView.mIsShortList && offset < 0) {
scaleRatio = -scaleRatio;
}
float scaleY = (float) (1 + scaleRatio);
if (offset > 0 || listView.mIsShortList) {
listView.mLastPivotY = 0.0f;
} else {
listView.mLastPivotY = (float) listView.getHeight();
}
listView.setPivotX(0);
listView.setPivotY(listView.mLastPivotY);
if (isTween) {
if (listView.getScaleY() != 1) {
canvas.scale(1, listView.getScaleY(), 0, listView.mLastPivotY);
listView.invalidate();
}
if (listView.mAnimatorSet != null) {
listView.mAnimatorSet.cancel();
}
listView.mAnimatorSet = new AnimatorSet();
ValueAnimator scaleBackAnimator = ValueAnimator.ofFloat(scaleY, 1);
scaleBackAnimator.setDuration(400);
scaleBackAnimator.setInterpolator(new BackEaseOutInterpolater());
scaleBackAnimator.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
listView.setScaleY((Float) animation.getAnimatedValue());
listView.invalidate();
}
});
if (listView.getScaleY() == 1) {
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(1, scaleY);
scaleAnimator.setDuration(200);
scaleAnimator.setInterpolator(new CircEaseOutInterpolator());
scaleAnimator.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
listView.setScaleY((Float) animation.getAnimatedValue());
listView.invalidate();
}
});
listView.mAnimatorSet.play(scaleAnimator).before(scaleBackAnimator);
} else {
listView.mAnimatorSet.play(scaleBackAnimator);
}
listView.mAnimatorSet.start();
return;
}
canvas.scale(1, scaleY, 0, listView.mLastPivotY);
listView.setScaleY(scaleY);
listView.invalidate();
}
Code for onTouchEvent
in ListView
:
@Override
public boolean onTouchEvent(MotionEvent ev) {
int y = (int) ev.getY();
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN://0
case MotionEvent.ACTION_POINTER_DOWN:
ListViewEnhance.onTouchDown(this, ev);
this.mDownMotionY = (y - (this.mLastY - this.mDownMotionY));
this.mLastY = y;
break;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_UP:
this.mLastY = y;
if (this.mIsTouching) {
this.mIsTouching = false;
}
break;
case MotionEvent.ACTION_CANCEL:
if (this.mIsTouching) {
this.mIsTouching = false;
ListViewEnhance.resetScale(this);
}
break;
case MotionEvent.ACTION_MOVE: {
int offset = (y - this.mDownMotionY);
if (!this.mIsTouching) {
ListViewEnhance.onTouchDown(this, ev);
}
this.mInertia = y - mDownMotionY;
if (ListViewEnhance.needListScale(this, offset)) {
this.mLastY = y;
return true;
} else {
if (y != this.mLastY) {
this.mLastY = y;
}
}
}
break;
}
return super.onTouchEvent(ev);
}
The Question:
Sometimes, the list remains stretched even after the touch is released. What could be causing this behaviour?
Stretched list after touch is released:
Apologies for the length of the question, but I thought the code might be of relevance. Any help will be much appreciated!