View动画的简单使用:
val button = findViewById<Button>(R.id.translation_button)
button.setOnClickListener {
val translationAnimation = AlphaAnimation(1f, 0f)
translationAnimation.duration = 4000
it.startAnimation(translationAnimation)
}
这是个很简单的透明度动画从1.0f到0.0f的。 下面我们来分析下源码:
public void startAnimation(Animation animation) {
animation.setStartTime(Animation.START_ON_FIRST_FRAME);
setAnimation(animation);
invalidateParentCaches();
invalidate(true);
}
```
先是设置调用setAnimation方法给自己设置了一个Animation对象,
````
public void setAnimation(Animation animation) {
mCurrentAnimation = animation;
if (animation != null) {
// If the screen is off assume the animation start time is now instead of
// the next frame we draw. Keeping the START_ON_FIRST_FRAME start time
// would cause the animation to start when the screen turns back on
if (mAttachInfo != null && mAttachInfo.mDisplayState == Display.STATE_OFF
&& animation.getStartTime() == Animation.START_ON_FIRST_FRAME) {
animation.setStartTime(AnimationUtils.currentAnimationTimeMillis());
}
animation.reset();
}
}
````
其实就是给mCurrentAnimation成员变量赋值,以后有用。
然后调用invalidate方法来重绘自己,这点流程就是通过ViewRootImpl调用scheduleTraversals()发起一个重绘请求,通过Choreographer发送一个异步消息,同时在Choregrapher中处理消息,最终会调用performTraversals()执行重绘。最终会调用View的draw方法进行绘制,
````
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
...
boolean concatMatrix = false;
final boolean scalingRequired = mAttachInfo != null && mAttachInfo.mScalingRequired;
//得到前面赋值的Animation,也就是我们需要执行的动画
final Animation a = getAnimation();
if (a != null) {
//执行动画
more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired);
concatMatrix = a.willChangeTransformationMatrix();
if (concatMatrix) {
mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
}
transformToApply = parent.getChildTransformation();
````
接着看:
```
private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime,
Animation a, boolean scalingRequired) {
Transformation invalidationTransform;
final int flags = parent.mGroupFlags;
final boolean initialized = a.isInitialized();
if (!initialized) { //如果没有初始化,那么就开始初始化
a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler);
onAnimationStart(); //回调接口的
}
final Transformation t = parent.getChildTransformation();
boolean more = a.getTransformation(drawingTime, t, 1f);
if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
if (parent.mInvalidationTransformation == null) {
parent.mInvalidationTransformation = new Transformation();
}
invalidationTransform = parent.mInvalidationTransformation;
//执行动画
a.getTransformation(drawingTime, invalidationTransform, 1f);
} else {
invalidationTransform = t;
}
return more;
}
```这个类在我们的AlphaAnimation中没有实现,这个是Animation的一个方法
public boolean getTransformation(long currentTime, Transformation outTransformation,
float scale) {
mScaleFactor = scale;
return getTransformation(currentTime, outTransformation);
}
```
```
public boolean getTransformation(long currentTime, Transformation outTransformation) {
if (mStartTime == -1) {
mStartTime = currentTime;
}
final long startOffset = getStartOffset();
final long duration = mDuration;
float normalizedTime;
if (duration != 0) {
//计算当前动画进度
normalizedTime = ((float) (currentTime - (mStartTime + startOffset))) /
(float) duration;
} else {
// time is a step-change with a zero duration
normalizedTime = currentTime < mStartTime ? 0.0f : 1.0f;
}
final boolean expired = normalizedTime >= 1.0f || isCanceled();
mMore = !expired;
if (!mFillEnabled) normalizedTime = Math.max(Math.min(normalizedTime, 1.0f), 0.0f);
if ((normalizedTime >= 0.0f || mFillBefore) && (normalizedTime <= 1.0f || mFillAfter)) {
if (!mStarted) {
//若当前为第一帧动画,会触发mListener.onAnimationStart()
fireAnimationStart();
mStarted = true;
if (NoImagePreloadHolder.USE_CLOSEGUARD) {
guard.open("cancel or detach or getTransformation");
}
}
if (mFillEnabled) normalizedTime = Math.max(Math.min(normalizedTime, 1.0f), 0.0f);
if (mCycleFlip) {
normalizedTime = 1.0f - normalizedTime;
}
//接着看下面的详细方法
getTransformationAt(normalizedTime, outTransformation);
}
if (expired) { //是否动画执行完成
if (mRepeatCount == mRepeated || isCanceled()) { //是否重复执行动画
if (!mEnded) {
mEnded = true;
guard.close();
//触发mListener.onAnimationEnd
fireAnimationEnd();
}
} else {
if (mRepeatCount > 0) {
mRepeated++;
}
if (mRepeatMode == REVERSE) {
mCycleFlip = !mCycleFlip;
}
mStartTime = -1;
mMore = true;
//触发mListener.onAnimationRepeated
fireAnimationRepeat();
}
}
if (!mMore && mOneMoreTime) {
mOneMoreTime = false;
return true;
}
return mMore;
}
```
```
getTransformationAt(normalizedTime, outTransformation);看下这个方法我们
```
public void getTransformationAt(float normalizedTime, Transformation outTransformation) {
//根据插值器mInterpolator调整动画进度
final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
//执行动画
applyTransformation(interpolatedTime, outTransformation);
}
```
applyTransformation(interpolatedTime, outTransformation);这个方法在Animation是个空方法,具体交给子类去实现,我们看下AlphaAnimation的
```
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float alpha = mFromAlpha;
t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
}
```
每一帧对应一个一个透明度,这样就实现了动画。