Android动画:两大必学动画详解之视图动画(View Animation)

引言

    Android动画分为两类, 分别是视图动画(View Animation)和属性动画(Property Animation)。其中View动画又分为帧动画(Frame Animation)和补间动画(Tween Animation),帧动画可以去加载一系列可绘制的Drawable逐帧实现动画,补间动画可以执行一系列简单的变化,这些变化包括旋转、位移、缩放等等。

1 帧动画(Frame Animation)

    帧动画顾名思义就是由图片按照顺序一帧一帧组合而成的动画。如下图1-1所示,图片按照run_1到run_16播放就可以形成一个跑步的动画。

    Android实现帧动画有两种方式,一种是xml文件实现,这种方式是帧动画最常用的实现方式,另一种是JAVA代码方式实现。它们的本质都是通过使用AnimationDrawable按顺序添加一系列Drawable来创建动画,并把动画赋值给View对象。

Android动画:两大必学动画详解之视图动画(View Animation)_第1张图片
图1-1 跑步素材

1.1 xml实现帧动画

    在Drawable下新建文件,然后使用animation-list并嵌套一系列的item,每一个item代表着一帧。

xml version="1.0" encoding="utf-8"?>

    android:oneshot="false" >

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

    下面是核心代码,首先获取AnimationDrawable,然后赋值给iamgeview做背景,最后调用AnimationDrawable的start、stop方法,就可以像图1-2一样开始动画或者停止动画。

//获取动画

animationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.run_anim);

img.setImageDrawable(animationDrawable);

//开始播放动画

start.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                if (animationDrawable !=null && !animationDrawable.isRunning()) {

                    animationDrawable.start();

                }

            }

    });

//停止播放动画

 stop.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                if (animationDrawable !=null &&animationDrawable.isRunning()) {

                    animationDrawable.stop();

                }

            }

 });

1.2 JAVA代码实现帧动画

    首先实例化AnimationDrawable,然后再获取Drawable下的资源文件,按照顺序逐帧添加到AnimationDrawable中,最后将AnimationDrawable赋值给View对象使用。

private void createAnimation() {

    animationDrawable =new AnimationDrawable();

    int id;

    for (int i =1; i <=16; i++) {

        id = getResources().getIdentifier("run_" + i,"drawable", getPackageName());

        //根据id获取到Drawable

        Drawable drawable = getResources().getDrawable(id);

        animationDrawable.addFrame(drawable,50);

    }

    //是否只运行一次

    animationDrawable.setOneShot(false);

    //给imageView设置动画

    img.setImageDrawable(animationDrawable);

}


Android动画:两大必学动画详解之视图动画(View Animation)_第2张图片
图1-2 Frame Animation 

2 补间动画(Tween Animation

    补间动画是通过执行一系列变化来达到动画效果的,这一系列的变化包括旋转(rotate)、位移(translate)、缩放(scale)和透明度(alpha),对应的类包括 RotateAnimation,TranslateAnimation,ScaleAnimation,AlphaAnimation,AnimationSet五个类,它们都继承自Animation抽象类。补间动画的实现方式也是两种,第一种是在xml文件中实现,另一种是JAVA代码实现。

    因为对应的五个类继承自Animation,所以它们也继承了Animation的属性,除此之外它们还有自己特有的属性。下列是继承自Animation的属性:

android:duration="long"    //定义动画运行时间,单位:毫秒。

android:fillAfter="boolean"    //定义动画结束后应用动画转变(是否停留在最后一帧)。默认值是false。

android:fillBefore="boolean"    //定义动画开始之前应用动画转变(是否直接从动画转变的第一帧开始)。默认值为true。

android:fillEnaabled="boolean"    //如果为true则应用fillBefore的值,否则忽略fillBefore的值。默认值为false。

android:interpolator="@[+][package:]type/name" | "?[package:]type/name"    //定义动画过渡用的插值器,例如:android:interpolator="@android:anim/linear_interpolator"。

android:repeatCount="int"    //定义动画重复多少次。默认值为0。

android:repeatMode=["restart " | "reverse"]      //定义repeatCount大于0时动画结束时的重复模式,restart 是从开始的地方重新播 放,reverse是从结束的地方重新播放。默认值是restart。

android:startOffset="int"    //定义动画开始前延迟,单位:毫秒。

android:zAdjustment=["bottom" | "normal" | " top"]    //允许调整动画在运行期间的z轴顺序。默认值为normal。

android:detackWallpaper="boolean"    //窗口动画特殊属性,如果这个窗口在壁纸之上,请不要使用它为墙纸设置动画。

2.1 旋转(rotate)

    RotateAnimation是控制对象旋转的动画,这个旋转发生在X-Y平面上。你可以指定旋转的中心点,其中(0,0)是左上角的点,如果你不指定中心点,那么(0,0)就是默认的旋转中心点。

    旋转特有的属性:

android:fromDegrees="float"    //定义动画开始前的角度。

android:toDegrees="float"     //定义动画结束时的角度。

android:pivotX="float"    //定义旋转点的X轴坐标,0是左上角。这个值可以是百分比(旋转坐标在自身x轴的百分比 )或者如果pivotXType 是ABSOLUTE这个值可以是一个绝对数字。

android:pivotY="float"   //定义旋转点的Y轴坐标,0是左上角。这个值可以是百分比( 旋转坐标在自身y轴的百分比 )或者如果 pivotXType 是 ABSOLUTE这个值可以是一个绝对数字。

下面两个属性pivotXType和pivotYType不能在XML中使用,例如使用了pivotXType会报错误“ error: attribute android:pivotXType not found. ”

pivotXType    //指定应该如何去解释pivotXValue ,可以使用其中一个Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF或 Animation.RELATIVE_TO_PARENT。

pivotYType    //指定应该如何去解释 pivotYValue ,可以使用其中一个Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF或 Animation.RELATIVE_TO_PARENT。

Animation.ABSOLUTE    //指定尺寸(dimension)是一个绝对像素数量。使用之后pivotX 或pivotY 的值都是绝对像素数量。

Animation.RELATIVE_TO_SELF       // 指定尺寸(dimension)是一个浮点数,这个浮点数用来乘动画对象的宽或高。例如使用之后动画最终的x轴 =(pivotX 的值) X (动画对象的宽 )。

Animation.RELATIVE_TO_PARENT    // 指定尺寸(dimension)是一个浮点数,这个浮点数用来乘动画父对象的宽或高。例如使用之后动画最终的x轴 =(pivotX 的值) X ( 动画父对象的宽 )。

2.1.1 在xml中实现旋转

 先看旋转效果图,如下图2-1:

Android动画:两大必学动画详解之视图动画(View Animation)_第3张图片
图2-1 旋转xml使用实例

    首先要做的就是在res下新建anim目录,然后在anim目录下创建m_rotate.xml,以rotate作为根元素进行编写,如下所示:

    android:duration="1000"

    android:fromDegrees="0" 

    android:interpolator="@android:anim/accelerate_interpolator" 

    android:pivotX="50%" 

    android:pivotY="50%"    

    android:toDegrees="720"    >

    编写完xml文件后,在java代码中使用AnimationUtils里的loadAnimation方法加载动画,并使用Animation。

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

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {  

         if (animation !=null) {

            img.startAnimation(animation);

          }

      }

});

2.1.2 纯代码实现旋转

    纯代码实现旋转需要使用到RotateAnimation类。RotateAnimation有以下四个构造方法,一般①不常用,使用②③④居多。

①RotateAnimation(Context context, AttributeSet attrs)

②RotateAnimation(float fromDegrees, float toDegrees)

③RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)

④RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

    因为前面没有pivotXType和pivotYType的实例,因此使用④构造RotateAnimation,先看效果图2-2 。

Android动画:两大必学动画详解之视图动画(View Animation)_第4张图片
图2-2 pivotXType和pivotYType使用实例

    构造方法很简单,pivotXType使用Animation.RELATIVE_TO_SELF,pivotXValue使用1f,因此动画对象的x轴旋转点从0向右边位移到自身1倍的位置上,而pivotXType也使用Animation.RELATIVE_TO_SELF,但是pivotXValue使用0f,因此Y轴旋转点没变。

animation =new RotateAnimation(0,720, Animation.RELATIVE_TO_SELF,1f, Animation.RELATIVE_TO_SELF,0f);

animation.setDuration(1000);

animation.setInterpolator(this, android.R.anim.accelerate_interpolator);

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        if (animation !=null) {

            img.startAnimation(animation);

        }

    }

});

2.2 平移(translate)

    TranslateAnimation是控制对象位置的动画。

    旋转特有的属性:

android:fromXDelta="float"    //在动画改变之前的X轴坐标

android:fromYDelta="float"    //在动画改变之前的X轴坐标

android:toXDelta="float"    //动画改变之后的X轴坐标

android:toYDelta="float"    //动画改编之后的X轴坐标

    下面四个属性 fromXType、 fromYType、toXType、toYType不能在XML中使用,例如使用了fromXType 会报错误“ error: attribute android:pivotXType not found. ”

fromXType//指定应该如何去解释 fromXType,可以使用其中一个Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF或 Animation.RELATIVE_TO_PARENT。

fromYType//指定应该如何去解释 fromYType,可以使用其中一个Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF或 Animation.RELATIVE_TO_PARENT。 

toXType//指定应该如何去解释  toXType,可以使用其中一个Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF或 Animation.RELATIVE_TO_PARENT。 

toYType//指定应该如何去解释  toYType,可以使用其中一个Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF或 Animation.RELATIVE_TO_PARENT。 

Animation.ABSOLUTE  //指定尺寸(dimension)是一个绝对像素数量。使用之后 pivotX 或 pivotY 的值都是绝对像素数量。

Animation.RELATIVE_TO_SELF       // 指定尺寸(dimension)是一个浮点数,这个浮点数用来乘动画对象的宽或高。例如使用之后动画最终的x轴 =(pivotX 的值) X ( 动画对象的宽 )。 

Animation.RELATIVE_TO_PARENT // 指定尺寸(dimension)是一个浮点数,这个浮点数用来乘动画父对象的宽或高。例如使用之后动画最终的x轴 =(pivotX 的值) X ( 动画父对象的宽 )。

2.2.1 在xml实现平移

    先看平移效果图,如下图2-3:

Android动画:两大必学动画详解之视图动画(View Animation)_第5张图片
图2-3 平移xml使用实例

     首先要做的就是在res下新建anim目录,然后在anim目录下创建m_translate.xml,以translate作为根元素进行编写,如下所示:

    android:duration="1000"

    android:fromXDelta="0"

    android:fromYDelta="0"

    android:toXDelta="50%"

    android:toYDelta="50%">

     编写完xml文件后,在java代码中使用AnimationUtils里的loadAnimation方法加载动画,并使用Animation。

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

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        if (animation !=null) {

            img.startAnimation(animation);

        }

    }

});

2.2.2 纯代码实现位移

    纯代码实现旋转需要使用到TranslateAnimation类。TranslateAnimation有以下三个构造方法,一般①不常用,使用②③居多。

①TranslateAnimation(Context context, AttributeSet attrs)

②TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)

③TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType,float fromYValue, int toYType, float toYValue)

     因为前面没有fromXType、 fromYType、toXType、toYType的实例,因此使用③构造RotateAnimation,先看效果图2-4 。

Android动画:两大必学动画详解之视图动画(View Animation)_第6张图片
图2-4 fromXType、 fromYType、toXType、toYType实例

    构造方法很简单,fromXType使用Animation.RELATIVE_TO_SELF,fromXValue使用1f,因此动画对象x轴的平移距离为自身宽的一倍,fromYType使用Animation.RELATIVE_TO_SELF,toYType使用1f,因此动画对象Y轴的平移距离为自身高的一倍。

animation =new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f, Animation.RELATIVE_TO_SELF,1f,Animation.RELATIVE_TO_SELF,0f, Animation.RELATIVE_TO_SELF,1f);

animation.setDuration(2000);

animation.setInterpolator(this, android.R.anim.linear_interpolator);

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        if (animation !=null) {

            img.startAnimation(animation);

        }

    }

});

2.3 缩放(scale)

    ScaleAnimation是控制对象缩放的动画,你可以指定缩放的中心点。

    缩放特有的属性:

android:fromXScale="float"    //动画开始前横轴缩放因子

android:fromYScale="float"    //动画开始前纵轴缩放因子

android:toXScale="float"    //动画结束时横轴缩放因子

android:toYScale="float"    //动画结束时纵轴缩放因子

android:pivotX="float"    //定义缩放点的X轴坐标,0是左上角。这个值可以是百分比(1.0是100% )或者如果pivotXType 是ABSOLUTE这个值可以是一个绝对数字。

android:pivotY="float"   //定义旋转点的Y轴坐标,0是左上角。这个值可以是百分比( 1.0是100%  )或者如果 pivotXType 是 ABSOLUTE这个值可以是一个绝对数字。

    下面两个属性pivotXType和pivotYType不能在XML中使用,例如使用了pivotXType会报错误“ error: attribute android:pivotXType not found. ”

pivotXType    //指定应该如何去解释pivotXValue ,可以使用其中一个Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF或 Animation.RELATIVE_TO_PARENT。

pivotYType    //指定应该如何去解释 pivotYValue ,可以使用其中一个Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF或 Animation.RELATIVE_TO_PARENT。

Animation.ABSOLUTE    //指定尺寸(dimension)是一个绝对像素数量。使用之后pivotX 或pivotY 的值都是绝对像素数量。

Animation.RELATIVE_TO_SELF       // 指定尺寸(dimension)是一个浮点数,这个浮点数用来乘动画对象的宽或高。例如使用之后动画最终的x轴 =(pivotX 的值) X (动画对象的宽 )。

Animation.RELATIVE_TO_PARENT    // 指定尺寸(dimension)是一个浮点数,这个浮点数用来乘动画父对象的宽或高。例如使用之后动画最终的x轴 =(pivotX 的值) X ( 动画父对象的宽 )。

2.3.1 在xml实现缩放

    先看看缩放效果图2-5:

Android动画:两大必学动画详解之视图动画(View Animation)_第7张图片
图2-5 缩放xml使用实例

    首先要做的就是在res下新建anim目录,然后在anim目录下创建m_scale.xml,以scale作为根元素进行编写,如下所示:

    android:duration="1000"

    android:fromXScale="1"

    android:fromYScale="1"

    android:pivotX="50%"

    android:pivotY="50%"

    android:toXScale="2"

    android:toYScale="2">

     编写完xml文件后,在java代码中使用AnimationUtils里的loadAnimation方法加载动画,并使用Animation。

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

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        if (animation !=null) {

            img.startAnimation(animation);

        }

    }

});

2.3.2 纯代码实现缩放

    纯代码实现旋转需要使用到ScaleAnimation类。ScaleAnimation有以下四个构造方法,一般①不常用,使用②③④居多。

①ScaleAnimation(Context context,AttributeSet attrs)

②ScaleAnimation(float fromX, float toX, float fromY, float toY)

③ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)

④ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue,int pivotYType, float pivotYValue)

  因为前面没有pivotXType和pivotYType的实例,因此使用④构造RotateAnimation,先看效果图2-6 。

Android动画:两大必学动画详解之视图动画(View Animation)_第8张图片
图2-6 pivotXType、pivotXType使用实例

 构造方法很简单,fromXScale使用了1f,toXScale使用了2f,所以x轴放大了1倍。fromYScale使用了1f,toYScale使用了1f,所以Y轴没变。pivotXType使用Animation.RELATIVE_TO_SELF,pivotXValue使用0.5f,因此动画对象的x轴缩放点从0向右边位移到自身0.5倍的位置上,而pivotXType也使用Animation.RELATIVE_TO_SELF,但是pivotXValue使用0.5f,因此动画对象的x轴缩放点从0向下边位移到自身0.5倍的位置上。

animation =new ScaleAnimation(1f,2f,1f,1f, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);

animation.setDuration(2000);

animation.setInterpolator(this, android.R.anim.linear_interpolator);

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        if (animation !=null) {

            img.startAnimation(animation);

        }

    }

});

2.4 透明度(alpha)

    AlphaAnimation是控制对象alpha等级的动画,用于淡入淡出效果。

    透明度特有的属性:

android:fromAlpha="float"    //开始动画alpha值,其中1.0表示完全不透明,0.0表示完全透明

android:toAlpha="float"    //结束动画alpha值。

 2.4.1 xml实现透明度变化

    先看看透明度变化效果图2-7:

Android动画:两大必学动画详解之视图动画(View Animation)_第9张图片
图2-7 透明度变化效果图

    首先要做的就是在res下新建anim目录,然后在anim目录下创建m_alpha.xml,以alpha作为根元素进行编写,如下所示:

    android:duration="1000"

    android:fromAlpha="1"

    android:toAlpha="0" />

    编写完xml文件后,在java代码中使用AnimationUtils里的loadAnimation方法加载动画,并使用Animation。

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

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        if (animation !=null) {

            img.startAnimation(animation);

        }

    }

});

2.4.2 纯代码实现透明度变化

    构造方法很简单,只有fromAlpha和toAlpha两个参数,代码效果图和图2-7是一样的。

animation =new AlphaAnimation(1.0f,0.0f);

animation.setDuration(1000);

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        if (animation !=null) {

            img.startAnimation(animation);

        }

    }

});

2.5 组合动画

    AnimationSet可以将每一个单一的动画组合而成一个动画。如果AnimationSet设置了子对象的属性,那么子对象的属性就会被AnimationSet覆盖(例如duration或fillBefore)。

    组合动画特有的属性:

android:shareInterpolator="boolean"    //如果为true,所有动画都使用AnimationSet的插值器。否则每个动画使用自己的插值器

    在组合动画中,部分AnimationSet的属性添加到AnimationSet会影响自己,有的属性则下推到子对象去使用,还有的属性会被忽略掉,如下:

duration, repeatMode, fillBefore, fillAfter:当这些属性在AnimationSet对象设置时,将会下推到子对象。

repeatCount, fillEnabled:AnimationSet会忽略掉这些属性

startOffset, shareInterpolator:这些属性将会应用到AnimationSet本身

2.5.1 xml实现组合动画

     先看看组合动画效果图2-8:

Android动画:两大必学动画详解之视图动画(View Animation)_第10张图片
图2-8 xml组合动画实例

    首先要做的就是在res下新建anim目录,然后在anim目录下创建m_set.xml,以set作为根元素进行编写,如下所示:

    android:fillAfter="true">

   

        android:duration="2000"

        android:fromXScale="1"

        android:fromYScale="1"

        android:pivotX="50%"

        android:pivotY="50%"

        android:toXScale="2"

        android:toYScale="2" />

   

        android:duration="2000"

        android:fromDegrees="0"

        android:pivotX="50%"

        android:pivotY="50%"

        android:toDegrees="720" />

     编写完xml文件后,在java代码中使用AnimationUtils里的loadAnimation方法加载动画,并使用Animation。

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

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        if (animation !=null) {

            img.startAnimation(animation);

        }

    }

});

2.5.2 纯代码实现组合动画

    纯代码实现旋转需要使用到AnimationSet类。AnimationSet有以下两个个构造方法,一般①不常用,使用②居多。

①AnimationSet(Context context,AttributeSet attrs)

②AnimationSet(boolean shareInterpolator)

     构造方法很简单,只有shareInterpolator一个参数,先创建AnimationSet,然后再使用addAnimation添加动画,我添加的是2.4.1的m_alpha和2.1.1的m_rotate动画,代码如下所示,效果图如图2-9。

animation =new AnimationSet(false);

((AnimationSet)animation).addAnimation(AnimationUtils.loadAnimation(this, R.anim.m_alpha));

((AnimationSet)animation).addAnimation(AnimationUtils.loadAnimation(this, R.anim.m_rotate));

animation.setDuration(2000);

start.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        if (animation !=null) {

            img.startAnimation(animation);

        }

    }

});

Android动画:两大必学动画详解之视图动画(View Animation)_第11张图片
2-9 纯代码组合动画实例

2.5.1 fillBefore、fillEnabled的使用

    fillBefore适用于AnimationSet动画,fillBefore在是在动画开始之前应用,但是在AnimationSet启动之前这个属性值不会被应用。

    先说说要实现的效果,第一种效果是先放大,再从原位置的90°旋转到720°,效果图如图2-10,第二种效果是放大的同时先应用旋转第一帧的属性,接着从旋转属性的第一帧开始旋转,效果图如图2-11。

Android动画:两大必学动画详解之视图动画(View Animation)_第12张图片
图2-10 第一种效果图
Android动画:两大必学动画详解之视图动画(View Animation)_第13张图片
图2-11 第二种效果图

    第一种效果图在xml中的代码如下所示,set 的android:fillBefore="false",scale的 android:fillEnabled="false" ,rotate的android:fillEnabled="true" ,第二章开头说过android:fillBefore是在android:fillEnabled="true"时才会被使用,android:fillBefore=“true”时是在动画开始前应用动画转化(也就是第一帧)。

    第二种效果图只是将 rotate中的fillEnabled设置为flase,也就是android:fillEnabled="false"。

    编写完xml文件后,在java代码中使用AnimationUtils里的loadAnimation方法加载动画,并使用Animation,java代码和2.5.1中的java代码一样。

    android:fillBefore="false">

   

        android:duration="1000"

        android:fromXScale="1"

        android:fromYScale="1"

        android:pivotX="50%"

        android:pivotY="50%"

        android:toXScale="2"

        android:toYScale="2"

        android:fillEnabled="false"/>

   

        android:duration="2000"

        android:fromDegrees="90"

        android:pivotX="50%"

        android:pivotY="50%"

        android:startOffset="1000"

        android:toDegrees="720"

        android:fillEnabled="true" />

  

你可能感兴趣的:(Android动画:两大必学动画详解之视图动画(View Animation))