package com.gnod.geekr.widget;
import com.gnod.geekr.app.AppConfig;
import com.gnod.geekr.tool.manager.Utils;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.ListView;
public class ParallaxScollListView extends ListView implements OnScrollListener {
ImageView mImageView;
int mDrawableMaxHeight = -1;
int mImageViewHeight = -1;
public final static double NO_ZOOM = 1;
public final static double ZOOM_X2 = 2;
private interface OnOverScrollByListener {
public boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent);
}
private interface OnTouchEventListener {
public void onTouchEvent(MotionEvent ev);
}
public ParallaxScollListView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public ParallaxScollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ParallaxScollListView(Context context) {
super(context);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
if (!Utils.hasHoneycomb()) {
AppConfig.sImageFetcher.setPauseWork(true);
}
} else {
AppConfig.sImageFetcher.setPauseWork(false);
}
}
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
boolean isCollapseAnimation = false;
isCollapseAnimation = onScroll.overScrollBy(deltaX, deltaY, scrollX,
scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,
maxOverScrollY, isTouchEvent);
return isCollapseAnimation ? true : super.overScrollBy(deltaX, deltaY,
scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,
maxOverScrollY, isTouchEvent);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
onTouched.onTouchEvent(ev);
return super.onTouchEvent(ev);
}
public void setParallaxImageView(ImageView iv) {
mImageView = iv;
mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
public void setViewsBounds(double zoomRatio) {
if (mImageViewHeight == -1) {
mImageViewHeight = mImageView.getHeight();
double imageRatio = ((double) mImageView.getDrawable()
.getIntrinsicWidth()) / ((double) mImageView.getWidth());
mDrawableMaxHeight = (int) ((mImageView.getDrawable()
.getIntrinsicHeight() / imageRatio) * (zoomRatio > 1 ? zoomRatio
: 1));
}
}
private OnOverScrollByListener onScroll = new OnOverScrollByListener() {
@Override
public boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if (mImageView.getHeight() <= mDrawableMaxHeight && isTouchEvent) {
if (deltaY < 0) {
if (mImageView.getHeight() - deltaY / 2 >= mImageViewHeight) {
mImageView.getLayoutParams().height = mImageView
.getHeight() - deltaY / 2 < mDrawableMaxHeight ? mImageView
.getHeight() - deltaY / 2
: mDrawableMaxHeight;
mImageView.requestLayout();
}
} else {
if (mImageView.getHeight() > mImageViewHeight) {
mImageView.getLayoutParams().height = mImageView
.getHeight() - deltaY > mImageViewHeight ? mImageView
.getHeight() - deltaY
: mImageViewHeight;
mImageView.requestLayout();
return true;
}
}
}
return false;
}
};
private OnTouchEventListener onTouched = new OnTouchEventListener() {
@Override
public void onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
if (mImageViewHeight - 1 < mImageView.getHeight()) {
ResetAnimimation animation = new ResetAnimimation(
mImageView, mImageViewHeight, false);
animation.setDuration(300);
mImageView.startAnimation(animation);
}
}
}
};
public class ResetAnimimation extends Animation {
int targetHeight;
int originalHeight;
int extraHeight;
View view;
boolean down;
protected ResetAnimimation(View view, int targetHeight, boolean down) {
this.view = view;
this.targetHeight = targetHeight;
this.down = down;
originalHeight = view.getHeight();
extraHeight = this.targetHeight - originalHeight;
}
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
int newHeight;
newHeight = (int) (targetHeight - extraHeight
* (1 - interpolatedTime));
view.getLayoutParams().height = newHeight;
view.requestLayout();
}
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
}
}