android动画程序员Android

爱她就要了解她之Android动画

2015-09-19  本文已影响625人  Jadyn

在Android中的动画主要有四种形式
1.Tween Aniamtion(变换动画)
2.Property Animation(属性动画)
3.Layout Animation(布局动画)
4.Frame Animation(逐帧动画)
在我们的应用中适当地使用动画,可以让我们的应用更加美观、柔和,对用户来说也会更加友好。

Tween Aniamtion

Tween Animation分为四种:
Alpha:渐变透明度动画
Scale:渐变尺寸缩放动画
Translate:位置移动变换动画
Rotate:旋转动画
共同属性:
(1)duration:动画持续时间。单位:毫秒
(2)reaptCount:动画重复次数
(3)reaptMode:动画重复模式(值:倒序重复 REVERSE,顺序重复 RESTART)
(4)startOffset:动画之间的时间间隔
(5)fillAfter:设置为true,表示动画转化效果在动画结束后被应用
(6)fillBefore:设置为true,表示动画转化效果在动画开始前被应用
(7)interprolator:动画插入器(加速、减速插入器)
以上的共同属性都可以通过set方式进行设置。
下面对这四种动画类型一一介绍
我们首先初始化一个View,以便下面演示

ImageView img = new ImageView(this)```
###1.Alpha
对view的透明度进行设置的取值范围是0.0~1.0
0.0表示完全透明     1.0表示完全不透明
Java Code:
```java
AlphaAnimation alpha = new AlphaAnimation(0F,1F);```
该构造方法中的第一个参数是初始透明度,第二个参数是最终透明度。
```java
alpha.setDuration(1000)//设置持续时间```
最后使用Vew的`startAnimation()`方法开始执行动画
```java
img.startAnimation(alpha)//开始执行动画```
XML配置文件
在xml中编写动画代码,需要在工程中的res目录下添加anim目录,然后在该目录中新建一个xml文件,然后如下编写:
```java
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="0"
    android:toAlpha="1"
    android:duration="1000">
</alpha>```
然后在Java Code中使用AnimationUtils类的`loadAnimation(Context context, int id)`将xml中的动画文件加载进来。同样对于View使用`startAnimation()`方法即可
###2.Scale
对View缩放的取值范围是从0~
0表示消失 1表示不缩放 >1表示放大
Java Code
ScaleAnimation有三个构造方法:
```java
public ScaleAnimation(float fromX, float toX, float fromY, float toY)//前两个参数是ViewX方向的缩放,后两个参数是ViewY方向的缩放
public ScaleAnimation(float fromX, float toX, float fromY, float toY,float pivotX, float pivotY)//前四个参数和第一个构造方法一样,最后两个参数是缩放的中心点
public ScaleAnimation(float fromX, float toX, float fromY, float toY,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)```
对于第三个构造方法中前四个参数和第一个构造方法一样,后面四个参数:pivotXType与pivotYType指缩放中心点的类型,其值在Animation类中有定义:
```java
RELATIVE_TO_SELF//指相对自身设置缩放中心
RELATIVE_TO_PARENT//指相对于view的父View设置缩放中心
ABSOLUTE//绝对的```
最后的两个参数需使用百分比的方式设置缩放中心,即值为0~1F。
XML配置文件
```java
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="0"
    android:toXScale="1"
    android:fromYScale="0"
    android:toYScale="1"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="1000">
</scale>```
使用XML文件配置动画时,pivotX与pivotY既可以使用百分比方式,也可以使用dp方式
###3.Translate
Java Code
Translate有两个构造方法:
```java
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)//很容易理解,即X方向的移动距离,Y方向的移动距离
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, 
                          int fromYType, float fromYValue, int toYType, float toYValue)```
第二个构造方法中的fromXType与fromYType与ScaleAnimation中的pivotXType的值是一样的,默认为相对自身的当前位置,其他参数与第一个构造方法的参数含义一样
XML配置文件
```java
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="100"
    android:fromYDelta="0"
    android:toYDelta="100"
    android:duration="1000">
</translate>```
比较简单,就不做详细介绍了。
###4.Rotate
Java Code
RotateAnimation也有三个常用的构造方法:
```java
public RotateAnimation(float fromDegrees, float toDegrees)//初始(from)的角度,结束时(to)的角度
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,int pivotYType, float pivotYValue)```
后面两个构造方法的参数其实和上面介绍的Scale是一样,就不做介绍了
XML配置文件
```java
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360">
</rotate>```
###5.Animation中的interprolator
Animation中的interprolator最底层的接口是
```java
public interface TimeInterpolator ```
他的子类有:
AccelerateInterpolator 加速插值器(动画速率开始很慢,然后逐渐加速)
DecelerateInterpolator 减速插值器(动画速率开始很快,然后逐渐减速)
AccelerateDecelerateInterpolator  加速减速插值器(动画速率开始慢然后块)
LinearInterpolator 线性插值器(最简单的插值器,即使动画匀速运动)
BounceInterpolator 弹跳插值器(在动画结束时使View呈弹跳状态)
AnticipateInterpolator 回荡秋千插值器(开始向后荡,然后向前荡的插值器)
CycleInterpolator 正弦周期变化插值器(动画循环播放特定的次数,速率改变沿着正弦曲线)
OvershootInterpolator 向前甩一定值后再回到原来位置
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
##Property Animation
属性动画实在API3.0之后出现的。属性动画相对于Tween传统动画具有一定的优越性,因为传统动画是不断调用onDraw()方法去重绘界面来实现动画效果,这在一定程度上必定会加大CPU负担,从而带来性能问题,并且传统动画只是重绘了界面,改变了View的显示位置,但是对用户的onClick等响应事件并没有发生相应的变化,所以传统动画并不适于那些具有交互的动画效果。而属性动画是改变View的属性值,真真正正改变了一个View,因此属性动画大大改变了传统动画的局限性。
ObjectAnimator
ObjectAnimator是属性动画中比较简单基础的类,我们可以使用以下方法为一个View添加动画效果。
```java
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)

第一个参数即要添加动画效果的View
第二个参数时属性名称。其实只要一个View的API中为某个属性设置setter/getter方法,我们就可以为它添加属性动画,这个属性名称可以为"rotation"、"translateX"、"translateY"、"X"、"Y"等View属性。
第三个参数是一个可变参数,即我们需要设置的动画值。例如:

ObjectAnimator.ofFloat(img, "translateX", 0F, 100F);//X方向的偏移
ObjectAnimator.ofFloat(img, "translateY", 0F, 100F);//Y方向的偏移```
多重动画的添加,我们可以使用如下方式
方式一:
```java
ObjectAnimator.ofFloat(img, "translateX", 0F, 100F).setDuration(1000).start();
ObjectAnimator.ofFloat(img, "translateY", 0F, 100F).setDuration(1000).start();
//这种方式并不是先执行“translateX”动画,再执行“translateY”动画,而是同时执行```
方式二:
```java
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("rotation",0F,360F);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translateX",0F,100F);
ObjectAnimator.ofPropertyValuesHolder(img,p1,p2).setDuration(1000).start();```
方式三:
```java
Animator anim1 = ObjectAnimator.ofFloat(img, "translateX", 0F, 100F);
Animator anim2 = ObjectAnimator.ofFloat(img, "translateY", 0F, 100F);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(anim1,anim2);
set.start();```
在AnimatorSet类中,有很多方法方便我们控制动画的执行流程
```java
public void playSequentially(Animator... items)//顺序执行items
public Builder with(Animator anim)//与某个动画同时执行
public Builder before(Animator anim)//在某个动画执行之前执行anim
public Builder after(Animator anim)//在某个动画执行后执行anim
...```
动画监听事件AnimatorListener
```java
ObjectAnimator anim = ObjectAnimator.ofFloat(root, "translateX", 0F, 100F);
anim.addListener(new Animator.AnimatorListener(){
    @Override
    public void onAnimationStart(Animator animation){}//动画开始时执行
    @Override
    public void onAnimationEnd(Animator animation){}//动画结束后执行
    @Override
    public void onAnimationCancel(Animator animation){}//动画被取消掉时执行
    @Override
    public void onAnimationRepeat(Animator animation){}//动画重复时执行
});```
当然有时候我们并不需要监听动画的这么多事件,那么我们可以使用AnimatorListenerAdapter这个抽象类,去重写我们需要监听的事件即可。
```java
anim1.addListener(new AnimatorListenerAdapter(){
    @Override
    public void onAnimationEnd(Animator animation){
        super.onAnimationEnd(animation);    
    }
});```
##Layout Animation
所谓布局动画即添加到布局的动画效果,并且动画效果会影响到布局的子对象。
为布局添加动画需要使用到LayoutAnimationController这个类,该类有两个常用构造方法
```java
public LayoutAnimationController(Animation animation)
public LayoutAnimationController(Animation animation, float delay)```
这两个构造比较容易理解,往构造方法中传递一个Animation参数即可。第二个构造方法中的delay(延迟)指子对象出现的先后延迟时间,即第一个View子对象开始出现后delay秒,第二个View子对象出现。
新建好LayoutAnimationController对象之后,使用
```java
view.setLayoutAnimation(LayoutAnimationController controller)```
这样我们就为布局添加好了动画效果。
LayoutAnimationController中有这样一个方法setOrder(int order),该方法指定布局中子View出现的先后顺序,API为我们制定了三个值,在LayoutAnimationController类中
```java
ORDER_NORMAL//顺序
ORDER_REVERSE//倒序
ORDER_RANDOM//随机```
为布局添加布局改变动画
在Layout的XML配置文件中使用
```java
android:animateLayoutChanges=["true"|"false"]```
这样就会为我们的布局添加一个系统默认的布局改变动画效果。
当然我们也可以自定义这个动画效果
使用view.setLayoutTransition(LayoutTransition transition)方法即为布局添加了一个默认的布局改变动画,如果想改变这个动画,需要使用到
```java
public void setAnimator(int transitionType, Animator animator)```
这个方法,第一个参数指布局改变的类型,在LayoutTransition 类中API为我们提供了5个值
```java
CHANGE_APPEARING//由于主容器新增加了一个View,而导致原来的View位置发生改变时触发的动画
CHANGE_DISAPPEARING//由于主容器移除了一个View,而导致原来的View位置发生改变时触发的动画
APPEARING//View显示时的动画
DISAPPEARING//View消失时的动画
CHANGING//包含上面所有的情况```
XML配置文件
我们也可以在XML文件中为布局设置布局动画
首先使用XML创建一个Tween Animation
然后使用XML通过以下语法创建一个布局动画
```java
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@[package:]anim/anim_resource_name"
    android:delay="0.5">
</layoutAnimation>```
根节点必须是layoutAnimation,android:animation指定义的Tween Animation
最后在layout布局中为布局使用android:layoutAnimation="@[package:]anim/anim_resource_name"
将我们编写的layoutAnimation文件的文件名传递进去即可。
##Frame Animation
这种类型的动画,在官方文档中是这样介绍的:
>Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制很相似,我们称之为逐帧动画。Frame动画既可以在XML文件中定义,也可以完全编码实现。

XML配置文件
在XML中进行定义时,文件既可以放在anim目录中也可以放在drawable文件中。语法如下:
```java
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
    android:oneshot=["true" | "false"] >  
    <item  
        android:drawable="@[package:]drawable/drawable_resource_name"  
        android:duration="integer" />  
</animation-list>```
animation-list作为根节点是必须的
android:oneshot若设值为true表示动画执行一次,若设值为false表示动画会重复执行。
每一个<item>元素表示一帧动画,android:drawable表示一帧所对应的图片,android:duration表示该帧所执行的时间。
Java Code
若以纯编码实现Frame动画需要用到AnimationDrawable类,该类是Drawable的子类。
在Java代码中我们可以使用setBackgroundResource()方法将我们XML中定义的Frame动画设置到ImageView上
```java
image.setBackgroundResource(R.anim.frame);  
AnimationDrawable anim = (AnimationDrawable) image.getBackground();  
anim.start();```
如果想要停止掉动画,只需调用anim.stop()方法即可。
还可以通过以下方式定义一个Frame动画
```java
AnimationDrawable frame = new AnimationDrawable();
for(int i = 0; i< 4; i++){
    int id = getResources().getIdentifier("f"+i,"drawable",getPackageName());
    Drawable drawable = getResources().getDrawable(id);
    frame.addFrame(drawable,300);
}
frame.setOneShot(true);
img.setBackgroundDrawable(frame);
frame.start();```
注意:对于AnimationDrawable不要在Activity的onCreate()方法中去掉用start()方法,因为此时窗口对象Window还没有初始化,AnimationDrawable不能被追加到Window中的视图对象中,所以并没有效果。解决办法可以是将animation的start放在一个按钮的点击事件或其他响应事件中,也可以在onWindowFocusChanged方法中开始执行动画,onWindowFocusChanged方法会在窗口初始化完成后被执行,在onCreate()方法之后执行。
上一篇下一篇

猜你喜欢

热点阅读