参考文章:Android 三种动画详解

一、view animation 视图动画(补间动画)

只能被用来设置View的动画。

可以使用xml或者java 代码进行实现

xml放在 res/anim/ 下

android:duration 动画持续时间,以毫秒为单位 android:fillAfter 如果设置为true,控件动画结束时,将保持动画最后时的状态 android:fillBefore 如果设置为true,控件动画结束时,还原到开始动画前的状态 android:fillEnabled 与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态 android:repeatCount 重复次数 android:repeatMode 重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。 android:interpolator 设定插值器,其实就是指定的动作效果,比如弹跳效果等,

java类名xml关键字描述信息AlphaAnimation 放置在res/anim/目录下渐变透明度动画效果RotateAnimation 放置在res/anim/目录下画面转移旋转动画效果ScaleAnimation 放置在res/anim/目录下渐变尺寸伸缩动画效果TranslateAnimation放置在res/anim/目录下画面转换位置移动动画效果AnimationSet 放置在res/anim/目录下一个持有其它动画元素alpha、scale、translate、rotate或者其它set元素的容器

xml属性java方法解释android:detachWallpapersetDetachWallpaper(boolean)是否在壁纸上运行android:durationsetDuration(long)动画持续时间,毫秒为单位android:fillAftersetFillAfter(boolean)控件动画结束时是否保持动画最后的状态android:fillBeforesetFillBefore(boolean)控件动画结束时是否还原到开始动画前的状态android:fillEnabledsetFillEnabled(boolean)与android:fillBefore效果相同android:interpolatorsetInterpolator(Interpolator)设定插值器(指定的动画效果,譬如回弹等)android:repeatCountsetRepeatCount(int)重复次数android:repeatModesetRepeatMode(int)重复类型有两个值,reverse表示倒序回放,restart表示从头播放android:startOffsetsetStartOffset(long)调用start函数之后等待开始运行的时间,单位为毫秒android:zAdjustmentsetZAdjustment(int)表示被设置动画的内容运行时在Z轴上的位置(top/bottom/normal),默认为normal

1、Alpha属性详解 透明度

xml属性java方法解释android:fromAlphaAlphaAnimation(float fromAlpha, …)动画开始的透明度(0.0到1.0,0.0是全透明,1.0是不透明)android:toAlphaAlphaAnimation(…, float toAlpha)动画结束的透明度,同上

2、Rotate属性详解 旋转

xml属性java方法解释android:fromDegreesRotateAnimation(float fromDegrees, …)旋转开始角度,正代表顺时针度数,负代表逆时针度数android:toDegreesRotateAnimation(…, float toDegrees, …)旋转结束角度,正代表顺时针度数,负代表逆时针度数android:pivotXRotateAnimation(…, float pivotX, …)缩放起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)android:pivotYRotateAnimation(…, float pivotY)缩放起点Y坐标,同上规律

3、Scale属性详解 缩放

xml属性java方法解释android:fromXScaleScaleAnimation(float fromX, …)初始X轴缩放比例,1.0表示无变化android:toXScaleScaleAnimation(…, float toX, …)结束X轴缩放比例android:fromYScaleScaleAnimation(…, float fromY, …)初始Y轴缩放比例android:toYScaleScaleAnimation(…, float toY, …)结束Y轴缩放比例android:pivotXScaleAnimation(…, float pivotX, …)缩放起点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)android:pivotYScaleAnimation(…, float pivotY)缩放起点Y轴坐标,同上规律

4、Translate属性详解 移动

xml属性java方法解释android:fromXDeltaTranslateAnimation(float fromXDelta, …)起始点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)android:fromYDeltaTranslateAnimation(…, float fromYDelta, …)起始点Y轴从标,同上规律android:toXDeltaTranslateAnimation(…, float toXDelta, …)结束点X轴坐标,同上规律android:toYDeltaTranslateAnimation(…, float toYDelta)结束点Y轴坐标,同上规律

5、使用

Animation animation = AnimationUtils.loadAnimation(this, R.anim.alphaanim);

btn.setAnimation(animation);

6、插值器Interpolator介绍

各种插值器都是实现了Interpolator接口,系统提供了许多已经实现好的插值器,具体如下:

java类xml id值描述AccelerateDecelerateInterpolator@android:anim/accelerate_decelerate_interpolator动画始末速率较慢,中间加速AccelerateInterpolator@android:anim/accelerate_interpolator动画开始速率较慢,之后慢慢加速AnticipateInterpolator@android:anim/anticipate_interpolator开始的时候从后向前甩AnticipateOvershootInterpolator@android:anim/anticipate_overshoot_interpolator类似上面AnticipateInterpolatorBounceInterpolator@android:anim/bounce_interpolator动画结束时弹起CycleInterpolator@android:anim/cycle_interpolator循环播放速率改变为正弦曲线DecelerateInterpolator@android:anim/decelerate_interpolator动画开始快然后慢LinearInterpolator@android:anim/linear_interpolator动画匀速改变OvershootInterpolator@android:anim/overshoot_interpolator向前弹出一定值之后回到原来位置PathInterpolator新增,定义路径坐标后按照路径坐标来跑。

6.1、插值器的使用

使用如下:

  ...

6.2、插值器的自定义

有时候你会发现系统提供的插值器不够用,可能就像View一样需要自定义。所以接下来我们来看看插值器的自定义,关于插值器的自定义分为两种实现方式,xml自定义实现(其实就是对现有的插值器的一些属性修改)或者java代码实现方式。如下我们来说说。

先看看XML自定义插值器的步骤:

在res/anim/目录下创建filename.xml文件。 修改你准备自定义的插值器如下:

   android:attribute_name="value"

   /> 在你的补间动画文件中引用该文件即可 可以看见上面第二步修改的是现有插值器的一些属性,但是有些插值器却不具备修改属性,具体如下: accelerateDecelerateInterpolator 无可自定义的attribute。 accelerateInterpolator android:factor 浮点值,加速速率(默认值为1)。 anticipateInterploator android:tension 浮点值,起始点后拉的张力数(默认值为2)。 anticipateOvershootInterpolator android:tension 浮点值,起始点后拉的张力数(默认值为2)。 android:extraTension 浮点值,拉力的倍数(默认值为1.5)。 bounceInterpolator 无可自定义的attribute。 cycleInterplolator android:cycles 整形,循环的个数(默认为1)。 decelerateInterpolator android:factor 浮点值,减速的速率(默认为1)。 linearInterpolator 无可自定义的attribute。 android:tension 浮点值,超出终点后的张力(默认为2)。 再来看看Java自定义插值器的(Java自定义插值器其实是xml自定义的升级,也就是说如果我们修改xml的属性还不能满足需求,那就可以选择通过Java来实现)方式。 可以看见上面所有的Interpolator都实现了Interpolator接口,而Interpolator接口又继承自 TimeInterpolator,TimeInterpolator接口定义了一个float getInterpolation(float input);方法,这个方法是由系统调用的,其中的参数input代表动画的时间,在0和1之间,也就是开始和结束之间。 如下就是一个动画始末速率较慢、中间加速的AccelerateDecelerateInterpolator插值器: public class AccelerateDecelerateInterpolator extends BaseInterpolator

      implements NativeInterpolatorFactory {

  ......

  public float getInterpolation(float input) {

      return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;

  }

  ......

} 到此整个补间动画与补间动画的插值器都分析完毕了,接下来看下别的动画。

二、帧动画

帧动画(Frame动画)也称作Drawable动画。

它允许像播放幻灯片一样的效果,这种动画实质是drawable,所以这种动画的定义方式文件医保放在res/drawable/目录下。

 

 

 

 

 

 

 

 

 

 

 

 

在java中使用

AnimationDrawable animDrawable = (AnimationDrawable) ContextCompat.getDrawable(mCtx, R.drawable.anim_loading_view);

animationDrawable.start();

imageView.setImageDrawable(animationDrawable);

*特别注意,AnimationDrawable的start()方法不能在Activity的onCreate方法中调运,因为AnimationDrawable还未完全附着到window上,所以最好的调运时机是onWindowFocusChanged()方法中。*

三、属性动画(Property Animation)

1、属性动画简介

Android3.0以后引入了属性动画,属性动画可以轻而易举的实现许多View动画做不到的事,譬如3D旋转一张图片。属性动画实现原理就是修改控件的属性值实现的动画

所有的属性动画的抽象基类就是Animator。

java类名xml关键字描述信息ValueAnimator放置在res/animator/目录下在一个特定的时间里执行一个动画TimeAnimator不支持/点我查看原因时序监听回调工具ObjectAnimator放置在res/animator/目录下一个对象的一个属性动画AnimatorSet放置在res/animator/目录下动画集合

所以可以看见,我们平时使用属性动画的重点就在于AnimatorSet、ObjectAnimator、TimeAnimator、ValueAnimator。

2、Java代码实现对象动画

首先我们先来看一下ObjectAnimator类最基本的方法

public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {

       ObjectAnimator anim = new ObjectAnimator(target, propertyName);

       anim.setFloatValues(values);

       return anim;

  }

方法中第一个参数Object target 的作用对象通常是View,也就是Android中的控件或布局。 方法中第二个参数String propertyName 通常是需要执行动画的属性,具体值如下表所示

属性值的用法rotation以屏幕方向为轴的旋转度数alpha透明度translationX / translationYX/Y方向的位移scaleX /scaleYX/Y方向的缩放倍数rotationX / rotationY以X/Y轴为轴的旋转度数

方法中第三个参数float... values 表示属性的变换范围,该参数可以传多个值。

添加一些代码来看一下效果

ImageView imageView = findViewById(R.id.imageView);

ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);

animator.setDuration(5000);

animator.start();

该动画效果表示控件ImageView的透明度在5s内由1变换到0,再由0变回 1。

ObjectAnimator的其他方法使用如下:

ImageView imageView = findViewById(R.id.imageView);

ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);

animator.setDuration(2000);

//动画延迟500ms执行

animator.setStartDelay(500);

//执行重复次数 +1

animator.setRepeatCount(3);

// 设置动画重复播放模式 RESTART -执行完一遍后重新执行

// REVERSE -执行完一遍后 从末位置往前执行

animator.setRepeatMode(ValueAnimator.RESTART);

//监听值变换

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

    @Override

    public void onAnimationUpdate(ValueAnimator animation) {

        Log.i("MainActivity","value:" +animation.getAnimatedValue());

    }

});

animator.start();

3、XML实现对象动画

在res目录下新建animator文件夹 animator文件夹下创建动画XML文件,如`animator_alpha.xml

   android:propertyName="alpha"

   android:valueFrom="1"

   android:valueTo="0"

   android:valueType="floatType" />

在xml中可直接用的属性动画节点有ValueAnimator、ObjectAnimator、AnimatorSet

 

      android:propertyName="string"

      android:duration="int"

      android:valueFrom="float | int | color"

      android:valueTo="float | int | color"

      android:startOffset="int"

      android:repeatCount="int"

      android:repeatMode=["repeat" | "reverse"]

      android:valueType=["intType" | "floatType"]/>

 

      android:duration="int"

      android:valueFrom="float | int | color"

      android:valueTo="float | int | color"

      android:startOffset="int"

      android:repeatCount="int"

      android:repeatMode=["repeat" | "reverse"]

      android:valueType=["intType" | "floatType"]/>

 

  ...

 

属性解释

xml属性解释android:ordering控制子动画启动方式是先后有序的还是同时进行。sequentially:动画按照先后顺序;together(默认):动画同时启动;

属性解释:

xml属性解释android:propertyNameString类型,必须要设置的节点属性,代表要执行动画的属性(通过名字引用),辟如你可以指定了一个View的”alpha” 或者 “backgroundColor” ,这个objectAnimator元素没有对外说明target属性,所以你不能在XML中设置执行这个动画,必须通过调用 loadAnimator()方法加载你的XML动画资源,然后调用setTarget()应用到具备这个属性的目标对象上(譬如TextView)。android:valueTofloat、int或者color类型,必须要设置的节点属性,表明动画结束的点;如果是颜色的话,由6位十六进制的数字表示。android:valueFrom相对应valueTo,动画的起始点,如果没有指定,系统会通过属性的get方法获取,颜色也是6位十六进制的数字表示。android:duration动画的时长,int类型,以毫秒为单位,默认为300毫秒。android:startOffset动画延迟的时间,从调用start方法后开始计算,int型,毫秒为单位。android:repeatCount一个动画的重复次数,int型,”-1“表示无限循环,”1“表示动画在第一次执行完成后重复执行一次,也就是两次,默认为0,不重复执行。android:repeatMode重复模式:int型,当一个动画执行完的时候应该如何处理。该值必须是正数或者是-1,“reverse”会使得按照动画向相反的方向执行,可实现类似钟摆效果。“repeat”会使得动画每次都从头开始循环。android:valueType关键参数,如果该value是一个颜色,那么就不需要指定,因为动画框架会自动的处理颜色值。有intType和floatType(默认)两种:分别说明动画值为int和float型。

Java代码中通过加载该xml启动动画

ImageView imageView = findViewById(R.id.imageView);

Animator anim = AnimatorInflater.loadAnimator(mCtx.this,R.animator.animator);

anim.setTarget(imageView);

anim.start();

4、值动画(ValueAnimator)

值动画通过控制值的变化,之后 手动赋值给对象的属性,从而实现动画。

ValueAnimator的核心方法如下:

ValueAnimator ofFloat(float... values) -- 浮点型数值

ValueAnimator ofInt(int... values) -- 整型数值

ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) -- 自定义对象类型

下面我们来添加值动画,在值动画的监听函数里 来获取值得变化,根据值的变化对控件设置相应的属性。这里的属性可以是控件的任意属性。

final ImageView imageView = findViewById(R.id.imageView);

ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);

anim.setDuration(5000);

anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

    @Override

    public void onAnimationUpdate(ValueAnimator animation) {

        float currentValue = (float) animation.getAnimatedValue();

        Log.d("MainActivity", "cuurent value is " + currentValue);

        imageView.setAlpha(currentValue);

    }

});

anim.start();

5、PropertyValueHolder

PropertyValueHolder可以让前面的一些动画同时执行。

ImageView imageView = findViewById(R.id.imageView);

PropertyValuesHolder alphaProper = PropertyValuesHolder.ofFloat("alpha", 0.5f, 1f);

PropertyValuesHolder scaleXProper = PropertyValuesHolder.ofFloat("scaleX", 0f, 1f);

PropertyValuesHolder scaleYProper = PropertyValuesHolder.ofFloat("scaleY", 0f, 1f);

PropertyValuesHolder translationXProper = PropertyValuesHolder.ofFloat("translationX", -100, 100);

PropertyValuesHolder translationYProper = PropertyValuesHolder.ofFloat("translationY", -100, 100);

PropertyValuesHolder rotationProper = PropertyValuesHolder.ofFloat("rotation", 0, 360);

ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageView, alphaProper,

        scaleXProper, scaleYProper,translationXProper,translationYProper,rotationProper);

animator.setDuration(5000);

animator.start();

6、动画组合(AnimatorSet)

前面的PropertyValueHolder类能实现将多个动画同时执行,AnimatorSet类不仅能让多个动画同时执行,还能让多个动画按一定的顺序执行,同时也能穿插多个动画同时执行。 主要的方法如下:

after(Animator anim) 将现有动画插入到传入的动画之后执行 after(long delay) 将现有动画延迟指定毫秒后执行 before(Animator anim) 将现有动画插入到传入的动画之前执行 with(Animator anim) 将现有动画和传入的动画同时执行

ImageView imageView = findViewById(R.id.imageView);

ObjectAnimator rotate = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);

ObjectAnimator translationX = ObjectAnimator.ofFloat(imageView, "translationX", -100, 100f);

ObjectAnimator translationY = ObjectAnimator.ofFloat(imageView, "translationY", -100, 100f);

ObjectAnimator scaleX = ObjectAnimator.ofFloat(imageView, "scaleX", 0, 1f);

ObjectAnimator scaleY = ObjectAnimator.ofFloat(imageView, "scaleY", 0, 1f);

ObjectAnimator alpha = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);

AnimatorSet animSet = new AnimatorSet();

animSet.play(rotate)

        .with(alpha)

        .after(scaleX)

        .before(translationX)

        .after(1000)

        .before(translationY)

        .with(scaleY);

animSet.setDuration(5000);

animSet.start();

7、插值器

animator.setInterpolator(new AccelerateInterpolator(5));

8、估值器(TypeEvaluator)

在前面的值动画(ValueAnimator)中和对象动画(ObjectAnimator)有一个传对象的方法:

ValueAnimator  ofObject(TypeEvaluator evaluator, Object... values)

ObjectAnimator ofObject(Object target, String propertyName,

           TypeEvaluator evaluator, Object... values)

MyView imageView = findViewById(R.id.myview);

ObjectAnimator anim = ObjectAnimator.ofObject(

       imageView,"color", new MyTypeEvaluator(),

       "#0000FF","#FF0000");

anim.setDuration(5000);

anim.start();

IntEvaluator:整数属性值。 FloatEvaluator:浮点数属性值。 ArgbEvaluator:十六进制color属性值。 TypeEvaluator:用户自定义属性值接口,譬如对象属性值类型不是int、float、color类型,你必须实现这个接口去定义自己的数据类型。

9、Java属性动画拓展之ViewPropertyAnimator动画

在Android API 12时,View中添加了animate方法,具体如下:

public class View implements Drawable.Callback, KeyEvent.Callback,        AccessibilityEventSource {     ......    

/**    

* This method returns a ViewPropertyAnimator object, which can be used to animate     * specific properties on this View.    

*    

* @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.     */    

   public ViewPropertyAnimator animate() {        

  if (mAnimator == null) {            

           mAnimator = new ViewPropertyAnimator(this);        

      }        

  return mAnimator;    

}                                                                                       ......                                                                             }

可以看见通过View的animate()方法可以得到一个ViewPropertyAnimator的属性动画(有人说他没有继承Animator类,是的,他是成员关系,不是之前那种继承关系)。

ViewPropertyAnimator提供了一种非常方便的方法为View的部分属性设置动画(切记,是部分属性),它可以直接使用一个 Animator对象设置多个属性的动画;在多属性设置动画时,它比 上面的ObjectAnimator更加牛逼、高效,因为他会管理多个属性的invalidate方法统一调运触发,而不像上面分别调用,所以还会有一些 性能优化。如下就是一个例子:

myView.animate().x(0f).y(100f).start();

10、Java属性动画拓展之LayoutAnimator容器布局动画

Property动画系统还提供了对ViewGroup中View添加时的动画功能,我们可以用LayoutTransition对 ViewGroup中的View进行动画设置显示。LayoutTransition的动画效果都是设置给ViewGroup,然后当被设置动画的 ViewGroup中添加删除View时体现出来。该类用于当前布局容器中有View添加、删除、隐藏、显示等时候定义布局容器自身的动画和View的动 画,也就是说当在一个LinerLayout中隐藏一个View的时候,我们可以自定义 整个由于LinerLayout隐藏View而改变的动画,同时还可以自定义被隐藏的View自己消失时候的动画等。

我们可以发现LayoutTransition类中主要有五种容器转换动画类型,具体如下:

LayoutTransition.APPEARING:当View出现或者添加的时候View出现的动画。 LayoutTransition.CHANGE_APPEARING:当添加View导致布局容器改变的时候整个布局容器的动画。 LayoutTransition.DISAPPEARING:当View消失或者隐藏的时候View消失的动画。 LayoutTransition.CHANGE_DISAPPEARING:当删除或者隐藏View导致布局容器改变的时候整个布局容器的动画。 LayoutTransition.CHANGE:当不是由于View出现或消失造成对其他View位置造成改变的时候整个布局容器的动画。

XML方式使用系统提供的默认LayoutTransition动画:

我们可以通过如下方式使用系统提供的默认ViewGroup的LayoutTransition动画:

android:animateLayoutChanges=”true”

在ViewGroup添加如上xml属性默认是没有任何动画效果的,因为前面说了,该动画针对于ViewGroup内部东东发生改变时才有效,所以当我们设置如上属性然后调运ViewGroup的addView、removeView方法时就能看见系统默认的动画效果了。

还有一种就是通过如下方式设置:

android:layoutAnimation=”@anim/customer_anim”

通过这种方式就能实现很多吊炸天的动画。

Java方式使用系统提供的默认LayoutTransition动画:

在使用LayoutTransition时,你可以自定义这几种事件类型的动画,也可以使用默认的动画,总之最终都是通过 setLayoutTransition(LayoutTransition lt)方法把这些动画以一个LayoutTransition对象设置给一个ViewGroup。

譬如实现如上Xml方式的默认系统LayoutTransition动画如下:

mTransitioner = new LayoutTransition();

mViewGroup.setLayoutTransition(mTransitioner);

稍微再高端一点吧,我们来自定义这几类事件的动画,分别实现他们,那么你可以像下面这么处理:

mTransitioner = new LayoutTransition();

......

ObjectAnimator anim = ObjectAnimator.ofFloat(this, "scaleX", 0, 1);

......//设置更多动画

mTransition.setAnimator(LayoutTransition.APPEARING, anim);

......//设置更多类型的动画               mViewGroup.setLayoutTransition(mTransitioner);

到此通过LayoutTransition你就能实现类似小米手机计算器切换普通型和科学型的炫酷动画了。

参考阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。