视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Animation动画的解析_html/css_WEB-ITnose
2020-11-27 16:04:48 责编:小采
文档


Animation在View的包下,我们通过Animation的原理也可知道,Animation离开了View就没有效果,为什么这么说呢?

Animation的动画原理

我们先看一个简单的Animation动画,AlphaAnimation:

public class AlphaAnimation extends Animation { private float mFromAlpha; private float mToAlpha; /** * Constructor used when an AlphaAnimation is loaded from a resource. * * @param context Application context to use * @param attrs Attribute set from which to read values */ public AlphaAnimation(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AlphaAnimation); mFromAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_fromAlpha, 1.0f); mToAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_toAlpha, 1.0f); a.recycle(); } /** * Constructor to use when building an AlphaAnimation from code * * @param fromAlpha Starting alpha value for the animation, where 1.0 means * fully opaque and 0.0 means fully transparent. * @param toAlpha Ending alpha value for the animation. */ public AlphaAnimation(float fromAlpha, float toAlpha) { mFromAlpha = fromAlpha; mToAlpha = toAlpha; } /** * Changes the alpha property of the supplied {@link Transformation} */ @Override protected void applyTransformation(float interpolatedTime, Transformation t) { final float alpha = mFromAlpha; t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime)); } @Override public boolean willChangeTransformationMatrix() { return false; } @Override public boolean willChangeBounds() { return false; } /** * @hide */ @Override public boolean hasAlpha() { return true; }}

代码非常简单,其核心代码就在

@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) { final float alpha = mFromAlpha; t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));}

通过interpolatedTime来不断给变alpha的值,我们就可以看到一个View实现透明度变化的动画效果!那么问题来了,谁在调用applyTransformation方法呢?跟进代码看到

public boolean getTransformation(long currentTime, Transformation outTransformation){}

中对applyTransformation做了调用,不用想了,getTransformation肯定是在View的startAnimation触发的!
是不是呢?

public void startAnimation(Animation animation) { animation.setStartTime(Animation.START_ON_FIRST_FRAME); setAnimation(animation); invalidateParentCaches(); invalidate(true); }

这里重新绘制了View,所以View的boolean draw(Canvas canvas, ViewGroup parent, long drawingTime)方法会被执行,为什么是draw而不是onDraw,我们看着么一句注解

 /** * This method is called by ViewGroup.drawChild() to have each child view draw itself. * This draw() method is an implementation detail and is not intended to be overridden or * to be called from anywhere else other than ViewGroup.drawChild(). */

而在draw()方法中有

final Animation a = getAnimation();if (a != null) { more = drawAnimation(parent, drawingTime, a, scalingRequired); concatMatrix = a.willChangeTransformationMatrix(); if (concatMatrix) { mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM; } transformToApply = parent.getChildTransformation();}

所以Animation得getTransformation的到执行,这就是Animation的实现原理。

但这好像对于我们来说意义不大,确实,因为我们不是Animation的缔造者,我们你只需要知道如何使用即可,就当前面热热身了!

Animation的使用

Animation的使用非常简单,Android中已经为我们定义好了四种Animation动画效果AlphaAnimation、RotateAnimation、ScaleAnimation、TranslateAnimation
以AlphaAnimation为例快速的说明一下其使用方法:

AlphaAnimation animation = new AlphaAnimation(1,0);animation.setDuration(2000) ;animation.setRepeat(2) ;view.startAnimation(animation);

ok,一个View的动画就实现了,其他三个动画效果也是类似的,非常简单!这里不重复了,我们重点来看一下如何自己定义一个Animation效果,还是通过一个案例来说明。

实现一个按钮放大的动画效果,这里放大不能出现拉伸,如果可以拉伸那就没意义了,因为系统已经为我们定义好了一个,ScaleAnimation就可以实现;

第一步 、继承Animation,
第二步 、重写applyTransformation方法
第三步、没了!

所以代码如下:

/** * Created by moon.zhong on 2015/4/23. */public class ScaleAnimation extends Animation { private View mTarget ; private int mOriginWidth ; private int mTargetWidth; private ViewGroup.LayoutParams mParams ; public ScaleAnimation(int mTargetWidth, View target) { this.mTarget = target; this.mOriginWidth = mTarget.getMeasuredWidth(); this.mTargetWidth = mTargetWidth; if (mOriginWidth == 0 ){ mTarget.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { mTarget.getViewTreeObserver().removeOnPreDrawListener(this); mOriginWidth = mTarget.getMeasuredWidth() ; return false; } }); } mParams = target.getLayoutParams() ; } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { /*interpolatedTime * 变化范围 * 0~1 * */ mParams.width = (int) (mOriginWidth + (mTargetWidth - mOriginWidth)*interpolatedTime) ; mTarget.setLayoutParams(mParams); }}

使用代码:

public void startAnimation(View view){ final float density = getResources().getDisplayMetrics().density; int width = (int) (300 * density); ScaleAnimation animation = new ScaleAnimation(width,mTargetView) ; animation.setDuration(2000); mTargetView.startAnimation(animation); }

效果图:

再来一张拉伸的效果图对比:

总结:

总体来说还是非常简单的,这里我只是定义了一个简单的动画,同理定义一个复杂一点的动画也是同样的操作,只是applyTransformation里面的代码写的多一点而已。
本篇blog的知识点主要有:
1、Animation的运用场景,作用于View中;
2、系统Animation的使用

AlphaAnimation animation = new AlphaAnimation(1,0);animation.setDuration(2000) ;animation.setRepeat(2) ;View.startAnimation(animation);

这种形式,当然还有读取xml的形式,这里没有提及到
3、自定义Animation
重写applyTransformation 方法

Demo源码
http://download.csdn.net/detail/jxxfzgy/8634819

下载本文
显示全文
专题