package android.widget;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
public class TwsStretchAnimation {
private final static String TAG = "SizeChange";
// interpolator
private Interpolator mInterpolator;
// need flexible view
private View mView;
private int mFlexibleType;
// current size
private int mCurrSize;
// rae size
private int mRawSize;
// min size
private int mMinSize;
// max size
private int mMaxSize;
// animator finished flag
private boolean isFinished = true;
private TYPE mType = TYPE.vertical;
// single frame time ms
private final static int FRAMTIME = 20;
// change view horizontal or vertical size
public static enum TYPE {
horizontal,
vertical
}
// animator running time
private int mDuration;
// animator starting time
private long mStartTime;
private float mDurationReciprocal;
// need change view increment
private int mDSize;
public TwsStretchAnimation(int maxSize, int minSize, TYPE type, int duration) {
if (minSize >= maxSize) {
throw new RuntimeException("view is maxsize not small minsize");
}
mMinSize = minSize;
mMaxSize = maxSize;
mType = type;
mDuration = duration;
}
public void setInterpolator(Interpolator interpolator) {
mInterpolator = interpolator;
}
public TYPE getmType() {
return mType;
}
public boolean isFinished() {
return isFinished;
}
public void setDuration(int duration) {
mDuration = duration;
}
private void changeViewSize() {
if (mView != null && mView.getVisibility() != View.GONE) {
LayoutParams params = mView.getLayoutParams();
if (mType == TYPE.vertical) {
params.height = mCurrSize;
} else if (mType == TYPE.horizontal) {
params.width = mCurrSize;
}
mView.setLayoutParams(params);
// Log.i(TAG, "CurrSize = " + mCurrSize + " Max=" + mMaxSize + " min="
// + mMinSize);
}
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// Log.i(TAG, "handleMessage what = " + msg.what);
switch (msg.what) {
case 1:
if(!computeViewSize()) {
mHandler.sendEmptyMessageDelayed(1, FRAMTIME);
}else {
mHandler.sendEmptyMessageDelayed(2, FRAMTIME);
}
break;
case 2:
if (animationlistener != null) {
animationlistener.animationEnd(mView, mFlexibleType);
}
break;
default:
break;
}
super.handleMessage(msg);
}
};
/**
* @return :true,show animator finished
*/
private boolean computeViewSize() {
if (isFinished) {
return isFinished;
}
int timePassed = (int) (AnimationUtils.currentAnimationTimeMillis() - mStartTime);
if (timePassed <= mDuration) {
float x = timePassed * mDurationReciprocal;
if (mInterpolator != null) {
x = mInterpolator.getInterpolation(x);
}
mCurrSize = mRawSize + Math.round(x * mDSize);
// Log.i(TAG, "x = " + x + "; mCurrSize = " + mCurrSize);
changeViewSize();
} else {
mCurrSize = mRawSize + mDSize;
changeViewSize();
isFinished = true;
// Log.i(TAG, "isFinished = " + isFinished + "; mCurrSize = " + mCurrSize);
}
return isFinished;
}
public void startAnimation(View view, int type) {
// Log.i(TAG, "isFinished = " + isFinished + "; type = " + type);
if (isFinished) {
mFlexibleType = type;
if (view != null) {
mView = view;
} else {
Log.e(TAG, "view is empty");
return;
}
isFinished = false;
mDurationReciprocal = 1.0f / (float) mDuration;
if (mType == TYPE.vertical) {
mRawSize = mCurrSize = mView.getHeight();
} else if (mType == TYPE.horizontal) {
mRawSize = mCurrSize = mView.getWidth();
}
// Log.i(TAG, "mRawSize=" + mRawSize + "; mCurrSize = " + mCurrSize
// + "; mMaxSize = " + mMaxSize
// + "; mMinSize = " + mMinSize);
if (mCurrSize > mMaxSize || mCurrSize < mMinSize) {
throw new RuntimeException(
"View size dissatisfy currentViewSize > mMaxSize || currentViewSize < mMinSize");
}
// starting animator time
mStartTime = AnimationUtils.currentAnimationTimeMillis();
if (mCurrSize < mMaxSize) {
mDSize = mMaxSize - mCurrSize;
} else {
mDSize = mMinSize - mMaxSize;
}
// Log.i(TAG, "mDSize=" + mDSize);
mHandler.sendEmptyMessage(1);
}
}
private AnimationListener animationlistener;
interface AnimationListener {
public void animationEnd(View v, int type);
}
public void setOnAnimationListener(AnimationListener listener) {
animationlistener = listener;
}
}