android动画详解(一)

Android动画详解

Android动画主要分为两类,传统动画和Android3.0之后出现的属性动画
传统动画又包括帧动画补间动画

补间动画

补间动画又可以分为四种形式,分别是 alpha(淡入淡出),translate(位移),scale(缩放大小),rotate(旋转)
一般采用xml实现

XML实现

alpha_anim.xml动画实现

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <!--透明度变换  -->
    <alpha
        android:duration="7000"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
</set>

scale_anim.xml动画实现

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">
    <!--尺寸收缩-->

    <scale
        android:duration="7000"
        android:fromXScale="0.5"
        android:fromYScale="0.5"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:pivotX="0%"
        android:pivotY="0%"
        android:toXScale="3.0"
        android:toYScale="3.0" />

</set>

rotate_anim.xml动画实现

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">

    <rotate
        android:duration="3000"
        android:fromDegrees="0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotX="0%"
        android:pivotY="0%"
        android:toDegrees="+180" />

</set>

translate_anim.xml动画实现

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">

    <!--位置转移动画-->
    <translate
        android:duration="5000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="300"
        android:toYDelta="200" />

</set>

在代码中可以通过

 Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate_anim);
 ivBack.startAnimation(animation);

这样的方式使用xml中的各种动画

纯代码实现

1.透明度动画

AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
alphaAnimation.setDuration(3000);
alphaAnimation.setFillAfter(true);
ivBack.startAnimation(alphaAnimation);

2.scale尺寸变换

ScaleAnimation scaleAnimation=new ScaleAnimation(0.0f,3.0f,0.0f,3.0f,150,500);
scaleAnimation.setDuration(4000);
scaleAnimation.setFillAfter(true);
ivBack.startAnimation(scaleAnimation);

3.translate位置变换

//xDelta 使用的是像素值
TranslateAnimation translateAnimation = new TranslateAnimation(0, 700, 0, 700);
translateAnimation.setDuration(4000);
ivBack.startAnimation(translateAnimation);

4.rotate角度变换

RotateAnimation rotateAnimation = new RotateAnimation(0, 180, 0, 0);
rotateAnimation.setDuration(5000);
rotateAnimation.setFillAfter(true);
ivBack.setAnimation(rotateAnimation);

我们给上述的图像本身做了点击事件

ivBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "点击事件", Toast.LENGTH_LONG).show();
            }
        });

可以看到,角度变换或者尺寸位置变换都不会改变view本身的位置,点击事件都对view的初始位置有效.

属性动画

所有补间动画的内容,都可以通过属性动画实现。
属性动画中比较重要的两个类

ValueAnimator
属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。

如果需要在1秒内对0到1的数值进行变换

ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Log.i("进度值", "进度值" + animation.getAnimatedValue());
            }
        });
valueAnimator.start();

可以看到动画执行过程中回调了很多参数

05-15 16:29:11.068 12018-12018/? I/进度值: 进度值0.0
05-15 16:29:11.085 12018-12018/? I/进度值: 进度值0.0
05-15 16:29:11.113 12018-12018/? I/进度值: 进度值0.0026845932
05-15 16:29:11.132 12018-12018/? I/进度值: 进度值0.0059125423
05-15 16:29:11.139 12018-12018/? I/进度值: 进度值0.010709554
05-15 16:29:11.156 12018-12018/? I/进度值: 进度值0.01690182
05-15 16:29:11.172 12018-12018/? I/进度值: 进度值0.023988664
05-15 16:29:11.189 12018-12018/? I/进度值: 进度值0.032835484
05-15 16:29:11.205 12018-12018/? I/进度值: 进度值0.04237941
05-15 16:29:11.222 12018-12018/? I/进度值: 进度值0.05378583
05-15 16:29:11.239 12018-12018/? I/进度值: 进度值0.06646466
05-15 16:29:11.255 12018-12018/? I/进度值: 进度值0.079527736
05-15 16:29:11.272 12018-12018/? I/进度值: 进度值0.09457022
05-15 16:29:11.288 12018-12018/? I/进度值: 进度值0.10978484
05-15 16:29:11.305 12018-12018/? I/进度值: 进度值0.12702942
05-15 16:29:11.322 12018-12018/? I/进度值: 进度值0.14533758
05-15 16:29:11.338 12018-12018/? I/进度值: 进度值0.16349372
05-15 16:29:11.355 12018-12018/? I/进度值: 进度值0.18371499
05-15 16:29:11.372 12018-12018/? I/进度值: 进度值0.20357156
05-15 16:29:11.388 12018-12018/? I/进度值: 进度值0.22548866
05-15 16:29:11.405 12018-12018/? I/进度值: 进度值0.24818844
05-15 16:29:11.421 12018-12018/? I/进度值: 进度值0.27021015

ObjectAnimator
ObjectAnimator是ValueAnimator的子类,它提供了对view操作的多种基础方法,如rotate,scale,translate,alpha。

XML实现

属性动画的属性值一般会牵扯到对象具体的属性,更多是通过代码动态获取,所以xml文件的实现会有点不方便。

android:ordering="together" 表明了当前set集合的动画播放顺序
together则表示同时并行加载
sequentially则表示顺序执行
对于多层动画播放顺序的集合,可以使用set集合嵌套执行

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">


    <objectAnimator
        android:duration="5000"
        android:propertyName="translationX"
        android:valueFrom="-500"
        android:valueTo="0"
        android:valueType="floatType" />

    <objectAnimator
        android:duration="5000"
        android:propertyName="translationY"
        android:valueFrom="500"
        android:valueTo="0"
        android:valueType="floatType" />


    <objectAnimator
        android:duration="5000"
        android:propertyName="alpha"
        android:valueTo="0f" />


</set>

多set嵌套

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">


    <objectAnimator
        android:duration="5000"
        android:propertyName="translationX"
        android:valueFrom="-500"
        android:valueTo="0"
        android:valueType="floatType" />


    <set>
        <objectAnimator
            android:duration="5000"
            android:propertyName="translationY"
            android:valueFrom="500"
            android:valueTo="0"
            android:valueType="floatType" />


        <objectAnimator
            android:duration="5000"
            android:propertyName="alpha"
            android:valueFrom="0f"
            android:valueTo="1f" />
    </set>

    <set

        android:ordering="together">
        <objectAnimator
            android:duration="5000"
            android:propertyName="scaleX"
            android:valueFrom="0.5f"
            android:valueTo="1f"
            android:valueType="floatType" />


        <objectAnimator
            android:duration="5000"
            android:propertyName="scaleY"
            android:valueFrom="0"
            android:valueTo="0.5f"
            android:valueType="floatType" />
    </set>


</set>

代码使用该动画集合

AnimatorSet set= (AnimatorSet) AnimatorInflater.loadAnimator(MainActivity.this,R.animator.object_anim);
set.setTarget(ivBack);
set.start();

代码实现属性动画

旋转动画

ObjectAnimator rotation = ObjectAnimator.ofFloat(ivBack, "rotation",0,90, 0f, 180f);
rotation.setDuration(2000);
rotation.start();

透明度变换

ObjectAnimator anim = ObjectAnimator.ofFloat(ivBack, "alpha", 1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f);
anim.setRepeatCount(-1);
anim.setRepeatMode(ObjectAnimator.REVERSE);
anim.setDuration(2000);
anim.start();

anim.setRepeatCount(-1);设置动画的循环次数, ValueAnimator.INFINITE即无限循环
android:repeatMode
重复模式,前提是android:repeatCount为-1
它有两种值:”reverse”和”repeat”,第一个表示反向重复,第二个为顺序重复。

用组合实现动画效果也是可以的

ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(ivBack, "alpha", 1.0f, 0.5f, 0.8f, 1.0f);
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(ivBack, "scaleX", 0.0f, 1.0f);
ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(ivBack, "scaleY", 0.0f, 3.0f);
ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(ivBack, "rotation", 0, 150);
ObjectAnimator transXAnim = ObjectAnimator.ofFloat(ivBack, "translationX", 100, 390);
ObjectAnimator transYAnim = ObjectAnimator.ofFloat(ivBack, "translationY", 100, 380);
AnimatorSet set = new AnimatorSet();
set.playTogether(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
// set.playSequentially(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
set.setDuration(3000);
set.start();

注:为了区分Property animation和View animation的资源文件,从Android 3.1(api 12)开始,Property animation的xml文件存在res/animator/目录下(View animation的存在res/anim/目录下), animator这个名是可选的。但是如果你想要使用Eclipse ADT plugin (ADT 11.0.0+)的布局编辑器,你就必须使用res/animator/目录,因为ADT只在该目录下寻找property animation的资源文件。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 2,758评论 0 10
  • 【Android 动画】 动画分类补间动画(Tween动画)帧动画(Frame 动画)属性动画(Property ...
    Rtia阅读 6,248评论 1 38
  • 一般常用的android动画有View Animation(视图动画)和Property Animation(属性...
    JCJIE阅读 454评论 0 2
  • 转载一篇高质量博文,原地址请戳这里转载下来方便今后查看。1 背景不能只分析源码呀,分析的同时也要整理归纳基础知识,...
    Elder阅读 1,954评论 0 24
  • Animation Animation类是所有动画(scale、alpha、translate、rotate)的基...
    四月一号阅读 1,936评论 0 10