7.1 View动画

Android动画深入分析

Android的动画可以分为三种,View动画(补间动画)帧动画属性动画

  • View动画通过对场景里的对象不断做图像变换(平移,旋转,缩放,透明度),从而产生动画效果,它是一种渐进式动画,并且View动画支持自定义。

  • 帧动画通过顺序播放一系列图像从而产生动画效果,可以简单理解为图片切换动画,很显然,如果图片过多过大就会导致OOM。

  • 属性动画通过动态地改变对象的属性从而达到动画效果。

1. View动画的种类

View动画的四种变换效果对应着Animation的四个子类:TranslateAnimationRotateAnimationScaleAnimationAlphaAnimation。这四种动画既可以通过XML来定义,也可以通过代码来动态创建,对于View动画来说,建议采用XML来定义动画,这是因为XML格式的动画可读性更好。

View Animation:

基于View的渐变动画,它只改变了View的绘制效果,而实际属性值未变。比如动画移动一个按钮位置,但按钮点击的实际位置仍未改变。在代码中定义动画,可以参考AnimationSet类和Animation的子类;而如果使用XML,可以在res/anim/文件夹中定义XML文件。

要使用View动画,首先要创建动画的XML文件,这个文件的路径为:res/anim/filename.xmlView动画的描述文件是有固定的语法的。

<?xml version="1.0" encoding="utf-8"?>
<set 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator=""
    android:shareInterpolator="">
    
    <translate
        android:fromXDelta=""
        android:toXDelta=""
        android:fromYDelta=""
        android:toYDelta=""/>
    
    <rotate
        android:fromDegrees=""
        android:toDegrees=""
        android:pivotX=""
        android:pivotY=""/>
    
    <scale
        android:fromXScale=""
        android:toXScale=""
        android:fromYScale=""
        android:toYScale=""
        android:pivotX=""
        android:pivotY=""/>
    
    <alpha
        android:fromAlpha=""
        android:toAlpha=""/>

</set>

从上面的语法可以看出,View动画既可以是单个动画,也可以由一系列动画组成。
<set>标签表示动画集合,对应AnimationSet类,它可以包含若干个动画,并且它的内部也是可以嵌套其他动画集合的,它的两个属性的含义如下:

  • android:interpolator
    表示动画集合所采用的插值器,插值器影响动画的速度,比如非匀速动画就需要通过插值器来控制动画的播放过程。这个属性可以不指定,默认为@android:anim/accelerate_decelerate_interpolator,即加速减速插值器。

  • android:shareInterpolator
    表示集合中的动画是否和集合共享同一个插值器,如果集合不指定插值器,那么子动画就需要单独指定所需的插值器或者使用默认值。

<translate>标签表示平移动画,对应TranslateAnimation类,它可以使一个View在水平和竖直方向完成平移的动画效果。

  • android:fromXDelta
    表示X的起始值,比如0
  • android:toXDelta
    表示X的结束值,比如100
  • android:fromYDelta
    表示Y的起始值
  • android:toYDelta
    表示Y的结束值
<?xml version="1.0" encoding="utf-8"?>
// 采用<translate /> 标签表示平移动画
<translate 
    xmlns:android="http://schemas.android.com/apk/res/android"

    // 以下参数是4种动画效果的公共属性,即都有的属性
    android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
    android:startOffset ="1000" // 动画延迟开始时间(ms)
    android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart
    android:repeatCount = “0” // 重放次数(所有动画的播放次数=重放次数+1),为infinite时无限重复
    android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
    
    // 以下参数是平移动画特有的属性
    android:fromXDelta="0" // 视图在水平方向x 移动的起始值
    android:toXDelta="500" // 视图在水平方向x 移动的结束值

    android:fromYDelta="0" // 视图在竖直方向y 移动的起始值
    android:toYDelta="500" // 视图在竖直方向y 移动的结束值

/>

// 在java中使用
btn1 = findViewById(R.id.btn1);
Animation translateAnimation = AnimationUtils.loadAnimation(this,R.anim.anim2);
btn1.startAnimation(translateAnimation);
https://www.jianshu.com/p/733532041f46的图片

<rotate>标签表示旋转动画,对应于RotateAnimation,它可以使View具有旋转的动画效果。

  • android:fromDegrees
    旋转开始的角度,比如0
  • android:toDegrees
    旋转结束的角度,比如180
  • android:pivotX
    旋转的轴点的X坐标
  • android:pivotY
    旋转的轴点的Y坐标
<?xml version="1.0" encoding="utf-8"?>
// 采用<rotate/> 标签表示是旋转动画
<rotate 
    xmlns:android="http://schemas.android.com/apk/res/android"

    // 以下参数是4种动画效果的公共属性,即都有的属性
    android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
    android:startOffset ="1000" // 动画延迟开始时间(ms)
    android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
    android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
    android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
    
    // 以下参数是旋转动画特有的属性
    android:duration="1000"
    android:fromDegrees="0" // 动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
    android:toDegrees="270" // 动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
    android:pivotX="50%" // 旋转轴点的x坐标
    android:pivotY="0" // 旋转轴点的y坐标
    // 轴点 = 视图缩放的中心点

 pivotX pivotY,可取值为数字,百分比,或者百分比p
     设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
     设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。
     设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT
     两个50%表示动画从自身中间开始,具体如下图

    />
https://www.jianshu.com/p/733532041f46的图

<scale>标签表示缩放动画,对应ScaleAnimation类,它可以使View具有放大或者缩小的动画效果。

xiaoyanger的图

  • android:fromXScale
    水平方向的缩放起始值,比如0.5
  • android:toXScale
    水平方向缩放的结束值,比如1.2
  • android:fromYScale
    竖直方向缩放的起始值
  • android:toYScale
    竖直方向缩放的结束值
  • android:pivotX
    缩放的轴点的X坐标,它会影响缩放的效果
  • android:pivotY
    缩放的轴点的Y坐标,它会影响缩放的效果

<alpha>标签表示透明度动画,对应AlphaAnimation,它可以改变View的透明度

  • android:fromAlpha
    表示透明度的起始值,比如0.1
  • android:toAlpha
    表示透明度的结束值,比如1

View动画还有一些常用的属性:

  • android:duration
    动画的持续时间
  • android:fillAfter
    动画结束以后,View是否停留在结束位置,true表示View停留在结束位置,false则不停留。

通过代码来应用动画

AlphaAnimation animation = new AlphaAnimation(0,1);
animation.setDuration(3000);
btn1.startAnimation(animation);

上面的代码,创建了一个透明度动画,将一个Button的透明度在3000ms内由0变为1,其他类型的View动画也可以通过代码来创建。

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

animation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
        Log.d("WM","start");
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        Log.d("WM","end");
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
        Log.d("WM","repeat");
    }
});

btn1.startAnimation(animation);
Drawable Animation(帧动画):

加载一系列Drawable资源来创建动画,这种传统动画某种程度上就是创建不同图片序列,顺序播放,就像电影胶片。

在代码中定义动画帧,使用AnimationDrawable类;XML文件能更简单的组成动画帧,在res/drawable文件夹,使用<animation-list>采用<item>来定义不同帧。感觉只能设置的属性是动画间隔时间。
帧动画是顺序播放一组预先定义好的图片,类似于电影播放,不同于View动画,系统提供了另外一个类AnimationDrawable来使用帧动画。

<?xml version="1.0" encoding="utf-8"?>
<animation-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false"> //oneshot代表着是否只展示一遍,设置为false会不停的循环播放动画

    <item android:drawable="@drawable/icon1" android:duration="150"/>
    <item android:drawable="@drawable/icon2" android:duration="150"/>
    <item android:drawable="@drawable/icon3" android:duration="150"/>
    <item android:drawable="@drawable/icon4" android:duration="150"/>
    <item android:drawable="@drawable/icon5" android:duration="150"/>
    <item android:drawable="@drawable/icon6" android:duration="150"/>

</animation-list>

注意:图片和XML文件都放在Drawable文件夹下。

btn1.setBackgroundResource(R.drawable.anim_list);

AnimationDrawable drawable = (AnimationDrawable) btn1.getBackground();

drawable.start();

帧动画的使用比较简单,但是比较容易引起OOM,所以在使用帧动画时应尽量避免使用过多尺寸较大的图片。

View动画是对View的影像做操作,并不能真正改变View的位置参数,包括宽和高,并且如果希望动画后的状态得以保留,还必须将fillAfter属性设置为true,否则动画完成后,其动画结果会消失。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容