8-1.动画基础

动画

动画分为两种, 帧动画(frame animation) 和 补间动画(tween animation).
 
研究: App Resources(看文档)
 

帧动画

1. 在 res/drawable 中创建一个xml文件, girl.xml 内容如下:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >
    <item
        android:drawable="@drawable/girl_1"
        android:duration="100"/>
    <item
        android:drawable="@drawable/girl_2"
        android:duration="100"/>
    <item
        android:drawable="@drawable/girl_3"
        android:duration="100"/>
    <item
        android:drawable="@drawable/girl_4"
        android:duration="100"/>
    ...
</animation-list>
用到图片都要放在drawable中.
 
2. 在布局文件中使用一个iv, 用于动画的显示
 
3. 在代码中调用
{{{class="brush:java"
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView iv = (ImageView) findViewById(R.id.iv);
        // 设置iv的动画背景
        iv.setBackgroundResource(R.drawable.girl);
        // 获取到动画背景资源
        rocketAnimation = (AnimationDrawable) iv.getBackground();
 
    }
 
    // 在4.0以上的模拟器上, 动画背景资源 (AnimationDrawable)一旦被得到, 就会自动播放动画 ,
    // 但是在2.3上, 需要一定的等待时间, 去调用 AnimationDrawable 的start方法
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 播放动画
        rocketAnimation.start();
        return super.onTouchEvent(event);
    }
 
}}}
 
 

补间动画

利用数学算法实现的动画效果. 有四种: 透明度, 旋转, 平移, 缩放, 以及这四者的组合.
 
透明度:
{{{class="brush:java"
        // 声明透明度变化的动画
        AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f);
        aa.setDuration(2000);  // 持续时间
        aa.setRepeatCount(1);  // 重复次数
        // 重复方式, RESTART: 从新开始, REVERSE: 反转
        aa.setRepeatMode(Animation.REVERSE);
        iv.startAnimation(aa);
}}}
 
旋转:
{{{class="brush:java"
        // 用参数最多的构造方法, 第一个参数从哪个角度, 第二个到哪个角度
        // 第三个相对的x轴, 第四个相对于x轴原点的位置, 第五六为 y...
        // 下面这个动画表示的就是, 相对于自己的中心旋转360度, 为什么?
        // 第3参数表示以相对的x轴即view的上边线, 第4参数0.5f即横坐标为一半, 同理5,6参数
        RotateAnimation ra = new RotateAnimation(0, 360,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f);
        ra.setDuration(2000);
        ra.setRepeatCount(2);
        ra.setRepeatMode(Animation.REVERSE);
        iv.startAnimation(ra);
}}}
 
平移:
{{{class="brush:java"
        // fromXType, fromXValue, toXType, toXValue, 后面四个是Y, 值可以为负数, 表示反方向.
        TranslateAnimation ta = new TranslateAnimation(
                Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0f,
                Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0.5f);
        ta.setDuration(2000);
        ta.setRepeatCount(0);
        ta.setRepeatMode(Animation.REVERSE);
        iv.startAnimation(ta);
}}}
 
缩放:
{{{class="brush:java"
        // fromX, toX, fromY, toY, pivotXType, 这四个决定了x,y轴的缩放量
        // pivotXValue, pivotYType, pivotYValue, 这四个决定了缩放中心点
        ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        sa.setDuration(2000);
        sa.setRepeatCount(2);
        sa.setRepeatMode(Animation.REVERSE);
        // 设置动画完成之后是否显示最终的样子.
        sa.setFillAfter(true);
        iv.startAnimation(sa);
}}}
 
组合:
{{{class="brush:java"
        //创建一个动画的集合, 参数表示是否共享 Interpolator. 关于Interpolator, 后面会介绍
        AnimationSet set = new AnimationSet(false);
        // 设置动画插入器, 表示输入x, 得到的 y, 即函数
        set.setInterpolator(new Interpolator() {
            @Override
            public float getInterpolation(float input) {
                return 0;
            }
        });
 
        AlphaAnimation aa = new AlphaAnimation(0.2f, 1.0f);
        aa.setDuration(2000);
        aa.setRepeatCount(1);
        aa.setRepeatMode(Animation.REVERSE);
 
        RotateAnimation ra = new RotateAnimation(0, 360,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        ra.setDuration(2000);
        ra.setRepeatCount(2);
        ra.setRepeatMode(Animation.REVERSE);
 
        TranslateAnimation ta = new TranslateAnimation(
                Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT,
                -0.5f, Animation.RELATIVE_TO_PARENT, 0,
                Animation.RELATIVE_TO_PARENT, -0.5f);
        ta.setDuration(2000);
        ta.setRepeatCount(2);
        ta.setRepeatMode(Animation.REVERSE);
 
        ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        sa.setDuration(2000);
        sa.setRepeatCount(2);
        sa.setRepeatMode(Animation.REVERSE);
        sa.setFillAfter(true);

        //把动画加到集合里
        set.addAnimation(sa);
        set.addAnimation(ta);
        set.addAnimation(ra);
        set.addAnimation(aa);
        iv.startAnimation(set);
}}}
 
注意: view设置动画, 当动画完成后, 无论最后动画效果怎样, iv还是停留在原来的位置, 只是图像变了位置.
 
 
== 使用资源创建动画 ==
在 res目录下创建一个 anim 文件夹, 在里面创建一个动画xml文件, 有5中根节点可供选择,
对应5种补间动画.
透明度:
{{{class="brush:xml"
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="0.2"
    android:toAlpha="1.0"
    android:duration="2000"
    >
</alpha>
}}}
对应的代码为:
{{{class="brush:java"
        // 声明透明度变化的动画
        Animation aa = AnimationUtils.loadAnimation(this, R.anim.alpha);
        iv.startAnimation(aa);
}}}
 
其他几种补间动画也都有相应的xml文件根节点
 
缩放:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="0.2"
    android:toXScale="1.0"
    android:fromYScale="0.2"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="2000"
     >
</scale>
        Animation sa = AnimationUtils.loadAnimation(this, R.anim.scale);
        iv.startAnimation(sa);
 
动画集, 动画的集合, 注意动画集是在同一时间执行所有动画, 而不是先执行一个再执行另一个.
另外, AnimationSet是Animation的子类. 动画集的拥有的属性,其中的动画的也会有, 并且动画集会覆盖其中的动画的属性
(旋转和平移):
<?xml version="1.0" encoding="utf-8"?>
        android:fillAfter="true">
    <rotate
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" >
    </rotate>
    <translate
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="50%p"
        android:toYDelta="0" >
    </translate>
</set>
50%p的意思是指父窗体的50%, 如果不写p表示自己的50%
        //创建一个动画的集合.
        Animation set =AnimationUtils.loadAnimation(this, R.anim.set);
        iv.startAnimation(set);

----------以下内容来自网上--------------
Frame Animation

Frame Animation是顺序播放事先做好的图像,跟电影类似。不同于animation package, Android SDK提供了另外一个类AnimationDrawable来定义、使用Frame Animation。

Frame Animation可以在XML Resource定义(还是存放到res\anim文件夹下),也可以使用AnimationDrawable中的API定义。由于Tween Animation与Frame Animation有着很大的不同,因此XML定义的格式也完全不一样,其格式是:首先是animation-list根节点,animation-list根节点中包含多个item子节点,每个item节点定义一帧动画,当前帧的drawable资源和当前帧持续的时间。下面对节点的元素加以说明: 

XML属性说明
drawable当前帧引用的drawable资源
duration当前帧显示的时间(毫秒为单位)
oneshot如果为true,表示动画只播放一次停止在最后一帧上,如果设置为false表示动画循环播放。
variablePaddingIf true, allows the drawable’s padding to change based on the current state that is selected.
visible规定drawable的初始可见性,默认为flase;

下面就给个具体的XML例子,来定义一帧一帧的动画:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
   
android:oneshot="true">
   
<item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
   
<item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
   
<item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>

上面的XML就定义了一个Frame Animation,其包含3帧动画,3帧动画中分别应用了drawable中的3张图片:rocket_thrust1,rocket_thrust2,rocket_thrust3,每帧动画持续200毫秒。

然后我们将以上XML保存在res/anim/文件夹下,命名为rocket_thrust.xml,显示动画的代码:

AnimationDrawable rocketAnimation;

public void onCreate(Bundle savedInstanceState){
 
super.onCreate(savedInstanceState);
  setContentView
(R.layout.main);

 
ImageView rocketImage =(ImageView) findViewById(R.id.rocket_image);
  rocketImage
.setBackgroundResource(R.anim.rocket_thrust);
  rocketAnimation
=(AnimationDrawable) rocketImage.getBackground();
}

public boolean onTouchEvent(MotionEvent event){
 
if(event.getAction() == MotionEvent.ACTION_DOWN){
rocketAnimation
.start();
   
return true;
 
}
 
return super.onTouchEvent(event);
}

代码运行的结果:3张图片按照顺序的播放一次.

有一点需要强调的是:启动Frame Animation动画的代码rocketAnimation.start();不能在OnCreate()中,因为在OnCreate()中AnimationDrawable还没有完全的与ImageView绑定,在OnCreate()中启动动画,就只能看到第一张图片。这里实在拖曳事件中实现的。

下面,阅读Android SDK中对AnimationDrawable的介绍,有个简单的了解:

AnimationDrawable

获取、设置动画的属性
int getDuration()获取动画的时长
int getNumberOfFrames()获取动画的帧数
boolean isOneShot()

 

Void setOneShot(boolean oneshot)

获取oneshot属性
设置oneshot属性
void inflate(Resurce r,XmlPullParser p,
AttributeSet attrs)
增加、获取帧动画
Drawable getFrame(int index)获取某帧的Drawable资源
void addFrame(Drawable frame,int duration)为当前动画增加帧(资源,持续时长)
动画控制
void start()开始动画
void run()外界不能直接掉调用,使用start()替代
boolean  isRunning()当前动画是否在运行
void stop()停止当前动画

Tween Animation

一个tween动画将对视图对象中的内容进行一系列简单的转换(位置,大小,旋转,透明性)。如果你有一个文本视图对象,你可以移动它,旋转它,让它变大或让它变小,如果文字下面还有背景图像,背景图像也会随着文件进行转换。

使用XML来定义Tween Animation

动画的XML文件在工程中res/anim目录,这个文件必须包含一个根元素,可以使<alpha><scale> <translate> <rotate>插值元素或者是把上面的元素都放入<set>元素组中,默认情况下,所以的动画指令都是同时发生的,为了让他们按序列发生,需要设置一个特殊的属性startOffset。动画的指令定义了你想要发生什么样的转换,当他们发生了,应该执行多长时间,转换可以是连续的也可以使同时的。例如,你让文本内容从左边移动到右边,然后旋转180度,或者在移动的过程中同时旋转,没个转换需要设置一些特殊的参数(开始和结束的大小尺寸的大小变化,开始和结束的旋转角度等等,也可以设置些基本的参数(例如,开始时间与周期),如果让几个转换同时发生,可以给它们设置相同的开始时间,如果按序列的话,计算开始时间加上其周期。

Tween Animation共同的节点属性

属性[类型]功能备注
Duration[long]属性为动画持续时间时间以毫秒为单位
fillAfter [boolean]当设置为true ,该动画转化在动画结束后被应用
fillBefore[boolean]当设置为true ,该动画转化在动画开始前被应用

interpolator

指定一个动画的插入器有一些常见的插入器
accelerate_decelerate_interpolator
加速-减速 动画插入器
accelerate_interpolator
加速-动画插入器
decelerate_interpolator
减速- 动画插入器
其他的属于特定的动画效果
repeatCount[int]动画的重复次数
RepeatMode[int]定义重复的行为1:重新开始  2:plays backward
startOffset[long]动画之间的时间间隔,从上次动画停多少时间开始执行下个动画
zAdjustment[int]定义动画的Z Order的改变0:保持Z Order不变
1:保持在最上层
-1:保持在最下层

表二

XML节点功能说明
alpha渐变透明度动画效果
<alpha
android:fromAlpha=”0.1″
android:toAlpha=”1.0″
android:duration=”3000″ />
fromAlpha

属性为动画起始时透明度

0.0表示完全透明
1.0表示完全不透明
以上值取0.0-1.0之间的float数据类型的数字

duration为动画持续时间,ms单位

toAlpha

属性为动画结束时透明度

表三

scale渐变尺寸伸缩动画效果
<scale
android:interpolator= “@android:anim/accelerate_decelerate_interpolator”
android:fromXScale=”0.0″
android:toXScale=”1.4″
android:fromYScale=”0.0″
android:toYScale=”1.4″
android:pivotX=”50%”
android:pivotY=”50%”
android:fillAfter=”false”
android:startOffset=“700”
android:duration=”700″
android:repeatCount=”10″ />
fromXScale[float] fromYScale[float]为动画起始时,X、Y坐标上的伸缩尺寸0.0表示收缩到没有
1.0表示正常无伸缩
值小于1.0表示收缩
值大于1.0表示放大
toXScale [float]
toYScale[float]
为动画结束时,X、Y坐标上的伸缩尺寸
pivotX[float]
pivotY[float]
为动画相对于物件的X、Y坐标的开始位置属性值说明:从0%-100%中取值,50%为物件的X或Y方向坐标上的中点位置

表四

translate画面转换位置移动动画效果
<translate
android:fromXDelta=”30″
android:toXDelta=”-80″
android:fromYDelta=”30″
android:toYDelta=”300″
android:duration=”2000″ />
fromXDelta
toXDelta
为动画、结束起始时 X坐标上的位置
fromYDelta
toYDelta
为动画、结束起始时 Y坐标上的位置

表五

rotate画面转移旋转动画效果
<rotate
android:interpolator=”@android:anim/accelerate_decelerate_interpolator”
android:fromDegrees=”0″
android:toDegrees=”+350″
android:pivotX=”50%”
android:pivotY=”50%”
android:duration=”3000″ />
fromDegrees为动画起始时物件的角度说明
当角度为负数——表示逆时针旋转
当角度为正数——表示顺时针旋转
(负数from——to正数:顺时针旋转)
(负数from——to负数:逆时针旋转)
(正数from——to正数:顺时针旋转)
(正数from——to负数:逆时针旋转)
toDegrees属性为动画结束时物件旋转的角度 可以大于360度
pivotX
pivotY
为动画相对于物件的X、Y坐标的开始位说明:以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置


 
 
 
 
 
 




posted @ 2016-10-01 00:29  杨伟乔  阅读(149)  评论(0编辑  收藏  举报