package com.cui.trypro.activity_animation.activityOptionCS.anim;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import com.cui.trypro.activity_animation.activityOptionCS.transition.TransitionCompat;
import com.cui.trypro.activity_animation.activityOptionCS.util.Position;
public class ViewAnim {
private View targetView;// 目标view,这里用于在没有传入toView,但需要动画结束后将某个view可见的情况
private long mAnimTime = 300;// 默认
private long mStartDelay = 0;
//private Animator currentAnimator = null;// 当前的动画对象
private TimeInterpolator mInterpolator = new AccelerateDecelerateInterpolator();
private TransitionCompat.ViewAnimationListener mListener;
private Rect mFinalBounds = null;
/**
* 开始执行补间动画的方法
* @param fromView:开始执行动画的view
* @param finalBounds:动画执行后view的目标位置,这里用rect做了封装
* @param startOffsetY:开始位置的Y轴偏移量
* @param finalOffsetY:结束位置的Y轴偏移量
*/
public void startViewTweensAnim(final View fromView,Rect finalBounds,int startOffsetY,int finalOffsetY) {
mFinalBounds = new Rect();
mFinalBounds = finalBounds;
startViewTweensAnim(fromView, (View)null, startOffsetY, finalOffsetY);
}
/**
* 开始执行补间动画的方法
* @param fromView:开始执行动画的view
* @param toView:用来给执行动画的view设定目标位置的view,两个view之间会自动产生补间动画
* @param startOffsetY:开始位置的偏移量
* @param finalOffsetY:目标位置的偏移量
*/
public void startViewTweensAnim(final View fromView,final View toView,int startOffsetY,int finalOffsetY) {
Rect startBounds = new Rect();
startBounds.set(Position.getGlobalVisibleRect(fromView));
Rect finalBounds = new Rect();
if (mFinalBounds != null) {
finalBounds.set(mFinalBounds);
}else {
toView.setVisibility(View.INVISIBLE);
finalBounds.set(Position.getGlobalVisibleRect(toView));
}
startBounds.offset(0, -startOffsetY);
finalBounds.offset(0, -finalOffsetY);
//设定拉伸或者旋转动画的中心位置,这里是相对于自身左上角
fromView.setPivotX(0f);
fromView.setPivotY(0f);
/**
* 通过动画来拉伸view时,view在动画过程中无法动态布局,因此要自己在update方法中重新写拉伸的算法
* 不能用scale的原因是,动画在执行时会通过:fromView.setScaleX(scaleX)来进行设置,这里仅仅是设置了拉伸比
* 但我们要的是重新绘制,不是拉伸,所以这里不能用拉伸动画
*/
//float scaleX = (float)finalBounds.width() / startBounds.width();
//float scaleY = (float)finalBounds.height() / startBounds.height();
AnimatorSet set = new AnimatorSet();
ObjectAnimator xAnim = ObjectAnimator.ofFloat(fromView, "x", startBounds.left, finalBounds.left);
ObjectAnimator yAnim = ObjectAnimator.ofFloat(fromView, "y", startBounds.top, finalBounds.top);
//ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(fromView, View.SCALE_X, 1f, scaleX);
//ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(fromView, View.SCALE_Y,1f, scaleY);
xAnim.addUpdateListener(new AnimUpdateListener(fromView, startBounds, finalBounds));
set.play(xAnim).with(yAnim);
set.setStartDelay(mStartDelay);
set.setDuration(mAnimTime);
set.setInterpolator(mInterpolator);
set.addListener(new AnimListener(fromView,toView));
set.start();
}
public void startViewSimpleAnim(final View fromView,Rect finalBounds,int
startOffsetY,int finalOffsetY, float startAlpha, float finalAlpha) {
Rect startBounds = new Rect();
startBounds.set(Position.getGlobalVisibleRect(fromView));
//设置偏移量
startBounds.offset(0, -startOffsetY);
finalBounds.offset(0, -finalOffsetY);
//设定拉伸或者旋转动画的中心位置,这里是相对于自身左上角
fromView.setPivotX(0f);
fromView.setPivotY(0f);
//计算拉伸比例
float scaleX = (float)finalBounds.width() / startBounds.width();
float scaleY = (float)finalBounds.height() / startBounds.height();
AnimatorSet set = new AnimatorSet();
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(fromView, "alpha", startAlpha, finalAlpha);
ObjectAnimator xAnim = ObjectAnimator.ofFloat(fromView, "x", startBounds.left, finalBounds.left);
ObjectAnimator yAnim = ObjectAnimator.ofFloat(fromView, "y", startBounds.top, finalBounds.top);
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(fromView, View.SCALE_X, 1f, scaleX);
ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(fromView, View.SCALE_Y,1f, scaleY);
set.play(alphaAnim).with(xAnim).with(yAnim).with(scaleXAnim).with(scaleYAnim);
set.setStartDelay(mStartDelay);
set.setDuration(mAnimTime);
set.setInterpolator(mInterpolator);
set.addListener(new AnimListener(fromView,null));
set.start();
}
/**
* @author:Jack Tony
* @tips :动画在执行时触发的方法,在这里自己重新设定view的参数,让内部布局重新绘制
* @date :2014-11-24
*/
private class AnimUpdateListener implements AnimatorUpdateListener{
View mView;
Rect mStartBounds, mFinalBounds;
public AnimUpdateListener(View view, Rect startBounds, Rect finalBounds) {
// TODO 自动生成的构造函数存根
mView = view;
mStartBounds = startBounds;
mFinalBounds = finalBounds;
}
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
if (valueAnimator.getCurrentPlayTime() <= valueAnimator.getDuration()) {
float fraction = valueAnimator.getAnimatedFraction();// 动画进度
float scaleXDuration = mFinalBounds.width() - mStartBounds.width();
float scaleYDuration = mFinalBounds.height() - mStartBounds.height();
mView.getLayoutParams().width = (int)(mStartBounds.width() + (scaleXDuration * fraction));
mView.getLayoutParams().height = (int)(mStartBounds.height() + (scaleYDuration * fraction));
if (mListener != null) {
mListener.onViewAnimationUpdate(mView, valueAnimator, fraction);
}
}
mView.requestLayout();
}
}
/**
* @author:Jack Tony
* @tips :动画执行的监听器,结束时进行图片的隐藏操作
* @date :2014-11-24
*/
private class AnimListener implements AnimatorListener{
private View mFromView,mToView;
public AnimListener(View fromView, View toView) {
// TODO 自动生成的构造函数存根
mFromView = fromView;
mToView = toView;
}
@Override
public void onAnimationStart(Animator animator) {
// TODO 自动生成的方法存根
mFromView.setVisibility(View.VISIBLE);
if (mListener != null) {
mListener.onViewAnimationStart(mFromView, animator);
}
}
@Override
public void onAnimationEnd(Animator animator) {
// 动画结束后开始动画的那个view变为不可见并且从父控件中移除,目标的view可见(如果有的话)
mFromView.setVisibility(View.INVISIBLE);
((ViewGroup)mFromView.getParent()).removeView(mFromView);
if (mToView != null) {
mToView.setVisibility(View.VISIBLE);
}
// targetView是在没有传入toView时,用来做目标view可见性改变的
if (targetView != null) {
targetView.setVisibility(View.VISIBLE);
}
if (mListener != null) {
mListener.onViewAnimationEnd(mFromView, animator);
}
}
@Override
public void onAnimationCancel(Animator animator) {
// TODO 自动生成的方法存根
if (mListener != null) {
mListener.onViewAnimationCancel(mFromView, animator);
}
}
@Override
public void onAnimationRepeat(Animator animation) {
// TODO 自动生成的方法存根
}
}
/**
* 设置动画差值器
* @param interpolator
*/
public void setTimeInterpolator(TimeInterpolator interpolator) {
mInterpolator = interpolator;
}
/**
* 动画初始化的监听器,用来初始化控件的各种属性
*/
public void addListener(TransitionCompat.ViewAnimationListener listener) {
mListener = listener;
}
public void setDuration(long time) {
mAnimTime = time;
}
public long getDuration() {
return mAnimTime;
}
public void setStartDelay(long delay) {
mStartDelay = delay;
}
public long getStartDelay() {
return mStartDelay;
}
/**
* 设定目标图片,这个图片仅仅会在动画结束后可见。没有其他作用
* @param view
*/
public void setTargetView(View view) {
targetView = view;
}
}