开源项目PullToZoomInListView的git地址:git地址
效果:
1.当往下拉时,顶部Image 放大,松手时,这个Image自动缩小到原始大小
2.当往上拉时,顶部Image上下(这个Image距离顶部 和 距离底部第一个Item)同时缩小
个人理解:
一:当往下拉时,顶部Image 放大
实现这个效果的做法:
1. new 一个FrameLayout和ImageView,设置这个ImageView的资源图片以及ScaleType,并用这个frameLayout .addView(ImageView),最后ListView添加headerView(FrameLayout)。
2. 自定义ScalingRunnable implements Runnable,在run方法里,循环post(this),重新设置FrameLayout的height(height通过Interpolator sInterpolator 来修改),来达到这个效果的。
private static final Interpolator sInterpolator = new Interpolator() {
public float getInterpolation(float t) {
t -= DEFAULT_MIN_SCALE;
return (t * t * t * t * t) + DEFAULT_MIN_SCALE;
}
};
class ScalingRunnable implements Runnable {
long mDuration;
boolean mIsFinished = true;
float mScale;
long mStartTime;
public boolean isFinished() {
return mIsFinished;
}
public void abortAnimation() {
mIsFinished = true;
}
public void startAnimation(long duration) {
mStartTime = SystemClock.currentThreadTimeMillis();
mDuration = duration;
mScale = ((float) mHeaderContainer.getBottom()) / ((float) mHeaderHeight);
mIsFinished = false;
post(this);
}
public void run() {
if (!mIsFinished && ((double) mScale) > 1.0d) {
float scale = mScale - ((mScale - DEFAULT_MIN_SCALE) * sInterpolator.getInterpolation((((float) SystemClock.currentThreadTimeMillis()) - ((float) mStartTime)) / ((float) mDuration)));
ViewGroup.LayoutParams params = mHeaderContainer.getLayoutParams();
if (scale <= DEFAULT_MIN_SCALE) {
mIsFinished = true;
params.height = mHeaderHeight;
} else {
params.height = (int) (((float) mHeaderHeight) * scale);
}
mHeaderContainer.setLayoutParams(params);
post(this);
}
}
}
二:当往上推时,顶部ImageView 既往上滑动,被状态栏覆盖,同时也被ListView headView下面的Item覆盖
实现这个效果的做法:
1. 被状态栏覆盖 是因为 listview本身 就有这个效果,当超过一屏,往上推时,上面的Item会被覆盖掉。
2. 被ListView headView下面的Item覆盖,是通过 ImageView 的scrollTo实现的。
float scrollY = (float) (mHeaderHeight - mHeaderContainer.getBottom());
if (scrollY > 0.0f && scrollY < ((float) mHeaderHeight)) {
mHeaderImage.scrollTo(0, -((int) (((double) scrollY) * 0.65d)));
} else if (mHeaderImage.getScrollY() != 0) {
mHeaderImage.scrollTo(0, 0);
}