Android入门——补间动画和帧动画应用小结

引言

动画Animations在App中的作用有多重要勿需多言,弹出式的PopupWindow、Tab切换、Loding等等。Android 3.0前,Android只支持两种动画模式:补间动画**Tween Animation和帧动画Frame animation;而在Android3.0时引入了一个新的动画系统:属性动画**property animation,三者在SDK中被称为property animation,view animation,drawable animation。 (可通过NineOldAndroids项目在3.0之前的系统中使用Property Animation。),接下来将分别总结整理下前两者以及相关类的关系的知识点。

一、补间动画 View Animation(Tween Animation)

1、补间动画概述

所谓补间动画即开发者只需指定开始、结束的关键帧,动画变化的“中间帧”则由系统根据相关算法计算补齐。所以View Animation就是一系列View形状的变换(如大小的缩放,透明度的改变,位置的改变),View animation只能应用于View对象,而且只支持一部分属性,如支持缩放旋转而不支持背景颜色的改变,它只是改变了View对象绘制的位置,而没有改变View对象本身,(比如:你有一个ImageButton,坐标(100,100),Width:200,Height:50,而你有一个动画使其变为Width:100,Height:100,你会发现动画过程中触发按钮点击的区域仍是(100,100)-(300,150))。

2、创建补间动画

补间动画的定义既可以用代码定义也可以用xml定义(建议用xml定义)。
可以给一个View同时设置多个动画,比如从透明至不透明的淡入效果,与从小到大的放大效果,这些动画既可以同时进行,也可以在一个完成之后开始另一个。

2.1、补间动画加速器——interpolator属性(默认为AccelerateDecelerateInterpolator)

Interpolater是一个接口,是根据特定算法计算出整个动画所需要动态插入帧的密度和位置,简而言之就是Interpolater负责控制动画的变化速度,使得基本动画能以匀速、加速、减速、抛物线变化。在补间动画里的四大动画的节点里有可以设置interpolator 属性(当然我们也可以实现Interpolater接口定义自己的加速器)Android里提供了以下五种加速器:

Java Code 应用的xml资源android:interpolator=”@android:anim/ 作用
LinearInterpolator linear_interpolator 匀速改变
AccelerateInterpolator accelerate_interpolator 在开始时改变较慢,然后开始加速
AccelerateDecelerateInterpolator accelerate_decelerate_interpolator 在开始和结束的时较慢,中间加速
CycleInterpolator cycle_interpolator 动画循环播放特定的次数,按正弦曲线改变
DecelerateInterpolator decelerate_interpolator 在开始地方速度较快,然后开始减速
/*如果是在代码上设置共享一个interpolator,则可以在AnimationSet设置interpolator*/
AnimationSet animationSet = new AnimationSet(true);
animationSet.setInterpolator(new AccelerateInterpolator());
/*如果不设置共享一个interpolator则可以在每一个Animation对象上面设置interpolator*/

AnimationSet animationSet = new AnimationSet(false);
alphaAnimation.setInterpolator(new AccelerateInterpolator());
rotateAnimation.setInterpolator(new DecelerateInterpolator());

2.2 使用xml定义补间动画(用xml定义的动画放在/res/anim 文件夹内)

补间动画有四种变化分别对应四个子节点:alphascaletranslaterotate和一个重要的属性interpolator(如果在一个set标签中包含多个动画效果,如果想让这些动画效果共享一个Interpolator,则设置android:shareInterpolator=”true”)

  • alpha 透明度变化
<!-- 浮点型值( 0.0f表示完全透明,1.0f表示完全不透明): fromAlpha 属性为动画起始时透明度 toAlpha 属性为动画结束时透明度 长整型值( 时间以毫秒为单位): duration 属性为动画持续时间 -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <alpha  android:duration="1000" android:fromAlpha="0.0" android:toAlpha="1.0" />
</set>
  • scale 大小缩放变化
<!-- 浮点型值(0.0表示收缩到没有,1.0表示正常无伸缩, 值小于1.0表示收缩,值大于1.0表示放大) fromXScale 属性为动画起始时 X轴的缩放比 toXScale 属性为动画结束时 X轴的缩放比 (pivotX,pivotY)缩放中心,其中从0%-100%中取值 ,50%为物件的X或Y方向坐标上的中点位置 布尔型值: fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用 -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <scale  android:duration="1000" android:fillAfter="false" android:fromXScale="0.0" android:fromYScale="0.0" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toXScale="1.4" android:toYScale="1.4" />
</set>
  • translate 位移变化
 <!-- 整型值: fromXDelta 属性为动画起始时 X坐标上的位置 toXDelta 属性为动画结束时 X坐标上的位置 fromYDelta 属性为动画起始时 Y坐标上的位置 toYDelta 属性为动画结束时 Y坐标上的位置 Ps: 没有指定fromXType toXType fromYType toYType 时候, 默认是以自己为相对参照物 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate  android:duration="2000" android:fromXDelta="30" android:fromYDelta="30" android:toXDelta="-80" android:toYDelta="300" />
</set>
  • rotate 旋转变化
    <!-- 浮点数型值: fromDegrees 属性为动画起始时物件的角度 toDegrees 属性为动画结束时物件旋转的角度 可以大于360度 Ps: 当角度为负数——表示逆时针旋转, 当角度为正数——表示顺时针旋转 (负数from——to正数:顺时针旋转),(负数from——to负数:逆时针旋转) (正数from——to正数:顺时针旋转),(正数from——to负数:逆时针旋转) pivotX 属性为动画相对于物件的X坐标的开始位置 pivotY 属性为动画相对于物件的Y坐标的开始位置 其中从0%-100%中取值,50%为物件的X或Y方向坐标上的中点位置 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <rotate  android:duration="4000" android:fromDegrees="0" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toDegrees="+350" />
</set>

xml文件的根元素可以为,,,,interpolator元素或(表示以上几个动画的集合,set可以嵌套)。默认情况下,所有动画是同时进行的,可以通过startOffset属性设置各个动画的开始偏移(开始时间)来达到动画顺序播放的效果。xml动画文件的使用可以参见这篇博文。

2.3、Java代码动态创建动画并应用

2.3.1、Android 动画类简述

我们都知道Android使用Animation代表抽像的动画基类,上文所说的四种动画效果和一个set节点也一定对应着四个继承了Animation的子类与一个动画集合类,即一种动画效果对应着一个class,关系如下:
Android入门——补间动画和帧动画应用小结_第1张图片

xml Java class
alpha AlphaAnimation
scale ScaleAnimation
translate TranslateAnimation
rotate RotateAnimation
set AnimationSet

2.3.2、Java代码应用补间动画步骤

  • 初始化对应的动画集合对象,用于添加动画效果(简单理解为盛装所有动画的容器)
AnimationSet animSets=new AnimationSet(true);
  • 通过四个动画子类的构造方法初始化动画对象
AlphaAnimation(float fromAlpha, float toAlpha);
ScaleAnimation(float fromX, float toX, float fromY, float toY);

ScaleAnimation scaleAnim=new 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)
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)
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)
  • 通过构造方法得到动画对象之后,还得通过一系列setXxx方法(Xxx代表xml中对应的属性节点),相当于xml中配置属性节点的值一般。
RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
                 Animation.RELATIVE_TO_SELF,0.5f,
                 Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(1000);

rotateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());

void    setRepeatCount(int repeatCount);
  • 设置动画监听器
    AnimationListener是一个监听器,该监听器在动画执行的各个阶段会得到通知,从而调用相应的方法
//设置监听
/** *onAnimationEnd(Animation animation) - 当动画结束时调用 *onAnimationRepeat(Animation animation) - 当动画重复时调用 *onAniamtionStart(Animation animation) - 当动画启动时调用 */
void setAnimationListener(Animation.AnimationListener listener)
  • 配置动画集开始的时间和其他属性
void    setStartOffset(long startOffset)

void    setStartTime(long startTimeMillis)
  • 再把各动画子类添加到动画集中
void addAnimation(Animation a)
  • 使用对应的View对象启动动画集
mImage.startAnimation(animationSet);

一个较完整的例子:

/*使用AnimationUtils装载动画xml配置文件*/
Animation animation = AnimationUtils.loadAnimation(
AnimationActivity.this, R.anim. doubleani);
/*启动动画集*/
image.startAnimation(animation);
AnimationSet animationSet = new AnimationSet(true);
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
       Animation.RELATIVE_TO_SELF,0.5f,
       Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(3000);
animationSet.addAnimation(rotateAnimation);//添加动画至集合
animationSet.addAnimation(alphaAnimation);
mImage.startAnimation(animationSet);//启动动画集

二、 帧动画(Frame-By-Frame Animation)

帧动画是一帧一帧的格式显示动画效果。创建帧动画我们除了通过在xml中用animation-list 作为根节点,item定义每一帧要显示的图片之外,也可以用Java代码的形式来创建帧动画。Drawable和xml帧动画可参见Android入门——Drawable与对应的资源xml的应用

1、Java代码动态创建帧动画

  • 通过构造方法初始化AnimationDrawable对象
AnimationDrawable animDrawble=new AnimationDrawable();
  • 再调用AnimationDrawable对象的addFrame(Drawable frame,int duration)方法添加帧
animDrawble.addFrame(Drawable drawable)
  • 设置相关属性
  • 调用AnimationDrawable对象的start()和stop()方法启动和停止动画。
animDrawble.start();

animDrawble.stop();

2、帧动画的应用

/*加载xml帧动画文件*/
ImageView img =(ImageView)findViewById(R.id.spinning_wheel_image);
img.setBackgroundResource(R.drawable.anim_maindraw);

AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();

frameAnimation.start();

start()之前要先stop(),不然在第一次动画之后会停在最后一帧,导致动画只触发一次;还有官方建议不要在onCreate中调用start,因为AnimationDrawable还没有完全跟Window相关联,如果想要界面显示时就开始动画的话,可以在onWindowFoucsChanged()中调用start()

三、LayoutAnimationsController

1、LayoutAnimationsController概述

LayoutAnimationsController可以用于实现使多个控件按顺序一个一个的显示

  • LayoutAnimationsController用于一个layout里面的控件,或者是一个ViewGroup里面的控件设置统一的动画效果。
  • 每一个控件都有相同的动画效果。
  • 控件的动画效果可以在不同的时间显示出来。
  • LayoutAnimationsController可以在xml文件当中设置,以可以在代码当中进行设置。

2、LayoutAnimationsController的应用

2.1、在xml中使用LayoutAnimationsController

  • 在res/anim文件夹下创建layoutAnimation文件
<!-- anim_layoutanim_main_list.xml android:delay - 动画间隔时间;子类动画时间间隔 (延迟)百分数如60% 也可以是一个浮点数 如“1.2”等 android:animationOrder - 动画执行的循序(normal:顺序,random:随机,reverse:反向显示) android:animation – 引用动画效果文件 -->
<layoutAnimation  xmlns:android="http://schemas.android.com/apk/res/android" android:delay="0.6" android:animationOrder="normal" android:animation="@anim/anim_main_list"/>
  • 定义将要被layoutAnimation引用的动画xml文件(即定义动画xml文件)
<!--anim_main_list.xml-->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" android:shareInterpolator="true">
    <alpha  android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="2000"/>
</set>
  • 在layout或ViewGroup及其子节点下的android:layoutAnimation使用layoutAnimation文件
<!--activity_main.xml-->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" >
    <ListView  android:id="@id/android:list" android:layout_width="fill_parent" android:layout_height="wrap_content" android:scrollbars="vertical" android:layoutAnimation="@anim/anim_layoutanim_main_list"/>
</LinearLayout>

应用在layout节点下就设置对应的android:layoutAnimation属性

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layoutAnimation="@anim/anim_layoutanim_main_list"
> 

2.2、在Java代码中使用LayoutAnimationsController

/*创建一个Animation对象:可以通过装载xml文件,或者是直接使用Animation的构造方法创建Animation对象*/
Animation animation = (Animation) AnimationUtils.loadAnimation(
                  AnimationActivity.this, R.anim.anim_main_list);
/*创建LayoutAnimationController对象*/
LayoutAnimationController controller = new LayoutAnimationController(animation); 

/*设置控件的显示顺序以及延迟时间*/
controller.setOrder(LayoutAnimationController.ORDER_NORMAL); 
controller.setDelay(0.6f); 
/*为ViewGrop(ListView)设置LayoutAnimationController属性*/
listView.setLayoutAnimation(controller);

你可能感兴趣的:(animation,帧动画,补间动画,Frame-Anim,Tween-Anim)