package com.todayinfo.ui.component.pulltozoomview;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import com.jinghua.todayinformation.R;
/**
* Author: ZhuWenWu Version V1.0 Date: 2014/11/10 14:25. Description:
* Modification History: Date Author Version Description
* ------------------------
* ----------------------------------------------------------- 2014/11/10
* ZhuWenWu 1.0 1.0 Why & What is modified:
*/
public class PullToZoomScrollViewEx extends PullToZoomBase<ScrollView> {
private static final String TAG = PullToZoomScrollViewEx.class
.getSimpleName();
private boolean isCustomHeaderHeight = false;// 自定义header高度之后可能导致zoomView拉伸不正确
private FrameLayout mHeaderContainer;
private LinearLayout mRootContainer;
private View mContentView;
private int mHeaderHeight;
private ScalingRunnable mScalingRunnable;
private static final Interpolator sInterpolator = new Interpolator() {
public float getInterpolation(float paramAnonymousFloat) {
float f = paramAnonymousFloat - 1.0F;
return 1.0F + f * (f * (f * (f * f)));
}
};
public PullToZoomScrollViewEx(Context context) {
this(context, null);
}
public PullToZoomScrollViewEx(Context context, AttributeSet attrs) {
super(context, attrs);
mScalingRunnable = new ScalingRunnable();
((InternalScrollView) mRootView)
.setOnScrollViewChangedListener(new OnScrollViewChangedListener() {
@Override
public void onInternalScrollChanged(int left, int top,
int oldLeft, int oldTop) {
if (isPullToZoomEnabled() && isParallax()) {
Log.d(TAG, "onScrollChanged --> getScrollY() = "
+ mRootView.getScrollY());
float f = mHeaderHeight
- mHeaderContainer.getBottom()
+ mRootView.getScrollY();
Log.d(TAG, "onScrollChanged --> f = " + f);
if ((f > 0.0F) && (f < mHeaderHeight)) {
int i = (int) (0.65D * f);
mHeaderContainer.scrollTo(0, -i);
} else if (mHeaderContainer.getScrollY() != 0) {
mHeaderContainer.scrollTo(0, 0);
}
}
}
});
}
@Override
protected void pullHeaderToZoom(int newScrollValue) {
Log.d(TAG, "pullHeaderToZoom --> newScrollValue = " + newScrollValue);
Log.d(TAG, "pullHeaderToZoom --> mHeaderHeight = " + mHeaderHeight);
if (mScalingRunnable != null && !mScalingRunnable.isFinished()) {
mScalingRunnable.abortAnimation();
}
ViewGroup.LayoutParams localLayoutParams = mHeaderContainer
.getLayoutParams();
localLayoutParams.height = Math.abs(newScrollValue) + mHeaderHeight;
mHeaderContainer.setLayoutParams(localLayoutParams);
if (isCustomHeaderHeight) {
ViewGroup.LayoutParams zoomLayoutParams = mZoomView
.getLayoutParams();
zoomLayoutParams.height = Math.abs(newScrollValue) + mHeaderHeight;
mZoomView.setLayoutParams(zoomLayoutParams);
}
}
/**
* 是否显示headerView
*
* @param isHideHeader
* true: show false: hide
*/
@Override
public void setHideHeader(boolean isHideHeader) {
if (isHideHeader != isHideHeader() && mHeaderContainer != null) {
super.setHideHeader(isHideHeader);
if (isHideHeader) {
mHeaderContainer.setVisibility(GONE);
} else {
mHeaderContainer.setVisibility(VISIBLE);
}
}
}
@Override
public void setHeaderView(View headerView) {
if (headerView != null) {
mHeaderView = headerView;
updateHeaderView();
}
}
@Override
public void setZoomView(View zoomView) {
if (zoomView != null) {
mZoomView = zoomView;
updateHeaderView();
}
}
/**
* 更新HeaderView 先移除-->再添加zoomView、HeaderView -->然后添加到listView的head
*/
private void updateHeaderView() {
if (mHeaderContainer != null) {
mHeaderContainer.removeAllViews();
if (mZoomView != null) {
mHeaderContainer.addView(mZoomView);
}
if (mHeaderView != null) {
mHeaderContainer.addView(mHeaderView);
}
}
}
public void setScrollContentView(View contentView) {
if (contentView != null) {
if (mContentView != null) {
mRootContainer.removeView(mContentView);
}
mContentView = contentView;
mRootContainer.addView(mContentView);
}
}
@Override
protected ScrollView createRootView(Context context, AttributeSet attrs) {
ScrollView scrollView = new InternalScrollView(context, attrs);
scrollView.setId(R.id.scrollview);
return scrollView;
}
@Override
protected void smoothScrollToTop() {
Log.d(TAG, "smoothScrollToTop --> ");
mScalingRunnable.startAnimation(200L);
}
@Override
protected boolean isReadyForPullStart() {
return mRootView.getScrollY() == 0;
}
@Override
public void handleStyledAttributes(TypedArray a) {
mRootContainer = new LinearLayout(getContext());
mRootContainer.setOrientation(LinearLayout.VERTICAL);
mHeaderContainer = new FrameLayout(getContext());
if (mZoomView != null) {
mHeaderContainer.addView(mZoomView);
}
if (mHeaderView != null) {
mHeaderContainer.addView(mHeaderView);
}
int contentViewResId = a.getResourceId(
R.styleable.PullToZoomView_contentView, 0);
if (contentViewResId > 0) {
LayoutInflater mLayoutInflater = LayoutInflater.from(getContext());
mContentView = mLayoutInflater.inflate(contentViewResId, null,
false);
}
mRootContainer.addView(mHeaderContainer);
if (mContentView != null) {
mRootContainer.addView(mContentView);
}
mRootContainer.setClipChildren(false);
mHeaderContainer.setClipChildren(false);
mRootView.addView(mRootContainer);
}
/**
* 设置HeaderView高度
*
* @param width
* 宽
* @param height
* 高
*/
public void setHeaderViewSize(int width, int height) {
if (mHeaderContainer != null) {
Object localObject = mHeaderContainer.getLayoutParams();
if (localObject == null) {
localObject = new ViewGroup.LayoutParams(width, height);
}
((ViewGroup.LayoutParams) localObject).width = width;
((ViewGroup.LayoutParams) localObject).height = height;
mHeaderContainer
.setLayoutParams((ViewGroup.LayoutParams) localObject);
mHeaderHeight = height;
isCustomHeaderHeight = true;
}
}
/**
* 设置HeaderView LayoutParams
*
* @param layoutParams
* LayoutParams
*/
public void setHeaderLayoutParams(LinearLayout.LayoutParams layoutParams) {
if (mHeaderContainer != null) {
mHeaderContainer.setLayoutParams(layoutParams);
mHeaderHeight = layoutParams.height;
isCustomHeaderHeight = true;
}
}
protected void onLayout(boolean paramBoolean, int paramInt1, int paramInt2,
int paramInt3, int paramInt4) {
super.onLayout(paramBoolean, paramInt1, paramInt2, paramInt3, paramInt4);
Log.d(TAG, "onLayout --> ");
if (mHeaderHeight == 0 && mZoomView != null) {
mHeaderHeight = mHeaderContainer.getHeight();
}
}
class ScalingRunnable implements Runnable {
protected long mDuration;
protected boolean mIsFinished = true;
protected float mScale;
protected long mStartTime;
ScalingRunnable() {
}
public void abortAnimation() {
mIsFinished = true;
}
public boolean isFinished() {
return mIsFinished;
}
public void run() {
if (mZoomView != null) {
float f2;
ViewGroup.LayoutParams localLayoutParams;
if ((!mIsFinished) && (mScale > 1.0D)) {
float f1 = ((float) SystemClock.currentThreadTimeMillis() - (float) mStartTime)
/ (float) mDuration;
f2 = mScale
- (mScale - 1.0F)
* PullToZoomScrollViewEx.sInterpolator
.getInterpolation(f1);
localLayoutParams = mHeaderContainer.getLayoutParams();
Log.d(TAG, "ScalingRunnable --> f2 = " + f2);
if (f2 > 1.0F) {
localLayoutParams.height = ((int) (f2 * mHeaderHeight));
mHeaderContainer.setLayoutParams(localLayoutParams);
if (isCustomHeaderHeight) {
ViewGroup.LayoutParams zoomLayoutParams;
zoomLayoutParams = mZoomView.getLayoutParams();
zoomLayoutParams.height = ((int) (f2 * mHeaderHeight));
mZoomView.setLayoutParams(zoomLayoutParams);
}
post(this);
return;
}
mIsFinished = true;
}
}
}
public void startAnimation(long paramLong) {
if (mZoomView != null) {
mStartTime = SystemClock.currentThreadTimeMillis();
mDuration = paramLong;
mScale = ((float) (mHeaderContainer.getBottom()) / mHeaderHeight);
mIsFinished = false;
post(this);
}
}
}
protected class InternalScrollView extends ScrollView {
private OnScrollViewChangedListener onScrollViewChangedListener;
public InternalScrollView(Context context) {
this(context, null);
}
public InternalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setOnScrollViewChangedListener(
OnScrollViewChangedListener onScrollViewChangedListener) {
this.onScrollViewChangedListener = onScrollViewChangedListener;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (onScrollViewChangedListener != null) {
onScrollViewChangedListener.onInternalScrollChanged(l, t, oldl,
oldt);
}
}
}
protected interface OnScrollViewChangedListener {
public void onInternalScrollChanged(int left, int top, int oldLeft,
int oldTop);
}
}