Android动画案例(三)属性动画

本文深入解析Android属性动画,对比补间动画,介绍ObjectAnimator类及AnimatorSet的使用方法,包括透明度、缩放、平移、旋转等动画效果的实现。

前方高能!!!有大量理论性的知识

Android系统在一开始的时候就提供了两种实现动画的方式,逐帧动画和补间动画

逐帧动画效果非常简单,就是让一张张单独的图片连续起来播放,类似于动画片的工作原理

补间动画就是则是可以对View进行一系列的动画操作,包括淡入淡出,缩放,平移,旋转四种

然而从Android 3.0 版本开始系统提供了一种全新的动画模式—属性动画
它的功能非常强大,弥补了之前补间动画的一些缺陷,(因为补间动画的可扩展性不强),几乎是可以完全替代补间动画了

那么补间动画是有哪些不能做,但是属性动画可以做到的呢?

1.补间动画只能操控View,属性动画可以对非View进行操作
比如说我们在自定义View的onDraw()方法中画的那个东西,如果加了一个动画给View,那么是操作整个View的而不是这个View中的Point
2.属性动画可以改变View的属性,补间动画仅仅改变的显示效果
比如用补间动画让一个Button向右平移,然后去点击平移后的Button,这个时候Button是不会触发点击事件的,因为Button的属性并没有真正的被改变
ObjectAnimator(最常用的类)

下面是我实现的工程截图
这里写图片描述
这里有动画的四大金刚—透明度,缩放,平移,旋转,这里会用xml和java代码两种形式去实现动画

使用xml文件去定义动画就要创建xml文件:
在drawable目录下创建 animator文件夹,我们所有的xml文件都会放在这个文件夹下面

其实套路都是一样的,那就以透明的为例将两种定义动画的方式都写上

透明度

xml定义动画

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType"
    android:propertyName="alpha"
    android:duration="2000"
    android:repeatCount="1"
    android:repeatMode="reverse"
    >

</objectAnimator>

valueFrom/valueTo:从哪个值到哪个值
valueType:值的类型
propertyName:动画名称
repeatCount:重复次数
repeatMode:重复的模式

这里要声明,属性动画和补间动画最后的效果是不一样的,如果使用补间动画定义,动画结束后View是会再返回到原来状态的,但是属性动画,如果不设置恢复到原来状态,View是会待在改变之后的状态的

为操控对象加载动画

 Animator animator = AnimatorInflater.loadAnimator(this, R.animator.alpha_animator);
        //给那个对象添加动画效果
        animator.setTarget(alpha_iv);
        animator.start();

java定义动画


 //实例化对象(添加动画的对象,动画名称,动画过程(最后三个参数))
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(alpha_iv, "alpha", 1.0f, 0f, 1.0f);
        //设置持续时间
        objectAnimator.setDuration(3000);
        objectAnimator.start();

缩放

//缩放
        ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(scaleX_iv, "scaleX", 1.0f, 3.0f, 1.0f);
        objectAnimator1.setDuration(3000);
        objectAnimator1.start();
        //缩放
        ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(scaleY_iv, "scaleY", 1.0f, 3.0f, 1.0f);
        objectAnimator2.setDuration(3000);
        objectAnimator2.start();

平移

//平移
        float currentX = translationX_iv.getTranslationX();//得到当前控件的X轴坐标
        ObjectAnimator objectAnimator5 = ObjectAnimator.ofFloat(translationX_iv, "translationX",
                currentX, -200f, currentX);
        objectAnimator5.setDuration(2000);
        objectAnimator5.start();
        float currentY = translationY_iv.getTranslationX();//得到当前控件的X轴坐标
        ObjectAnimator objectAnimator6 = ObjectAnimator.ofFloat(translationY_iv, "translationY",
                currentY, -200f, currentX);
        objectAnimator6.setDuration(2000);
        objectAnimator6.start();

旋转

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(rotation_iv, "rotation", 0f, 360f);
        objectAnimator1.setDuration(2000);
        objectAnimator1.start();
        //效果为X轴为旋转轴,上下翻转
        ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(rotationX_iv, "rotationX", 0f, 360f);
        objectAnimator2.setDuration(2000);
        objectAnimator2.start();
        //效果为y轴为旋转轴,上下翻转
        ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(rotationY_iv, "rotationY", 0f, 360f);
        objectAnimator3.setDuration(2000);
        objectAnimator3.start();

有木有发现套路都是一样的呢,对!就是一样的
1.实例化ObjectAnimator 类的操作对象
ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(添加动画的对象,动画名称,动画过程);
动画过程这里可以是多个参数
2.设置可持续时间
3.start();方法开始动画

很多人会发现Obj的构造方法是非常强大的,因为它的第二个参数是一个字符串,这个字符串可以随便定义,你可以定义一个name,也可以定义一个age(几岁到几岁),alpha本来不是textView的一个属性,但是即使是随意定义也是要有根据的;虽然一个View没有alpha的属性 ,但是一个View有get/setAlpha();的方法的,这个动画的子类就是调用set/get的方法更改属性的,如果你想要更改某种属性,你的第一个参数中的对象要存在这个属性的get/set方法,所以View中也是存在 getRotation();setTranslationX()等这些方法的,可以去View的源码中去查找一下

组合

组合这里我个人认为还是用java代码去定义比较简单,并且对Xml的理解我并没有掌握的很透彻,所以有些下次和技术上的壁垒,希望看我博客的大神们可以谅解

java文件定义动画

//平移
        float currentX = translationX_iv.getTranslationX();//得到当前控件的X轴坐标
        ObjectAnimator tran = ObjectAnimator.ofFloat(set_java_iv, "translationX",
                currentX, -200f, currentX);
        //旋转
        ObjectAnimator rotate=ObjectAnimator.ofFloat(set_java_iv,"rotation",0f,360f);
        //透明度
        ObjectAnimator alpha=ObjectAnimator.ofFloat(set_java_iv,"alpha",1f,0f,1f);
        //缩放
        ObjectAnimator scale = ObjectAnimator.ofFloat(set_java_iv, "scaleX", 1.0f, 3.0f, 1.0f);
        //组合动画的类
        AnimatorSet animatorSet=new AnimatorSet();
        animatorSet.play(rotate).with(scale).with(alpha).after(tran);
        animatorSet.setDuration(5000);
        animatorSet.start();

前面都是对动画的定义,后面是将动画组合起来

after(Animator anim): 将现有动画插入到传入的动画之后执行
after(long delay):将现有动画延迟指定毫秒后执行
before(Animator anim):将现有动画插入到传入的动画之前执行
with(Animator anim):将现有动画和传入的动画同时执行

所以之后的动画执行顺序为:先向左平移,再旋转,缩放,透明度同时执行

xml定义动画

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">
    <!--从左侧平移进来的动画-->
    <objectAnimator
        android:duration="2000"
        android:propertyName="translationX"
        android:valueFrom="250"
        android:valueTo="0"
        android:valueType="floatType" />
    <!--动画的嵌套:同时进行旋转和透明度的变化-->
    <set android:ordering="together">
        <objectAnimator
            android:duration="3000"
            android:propertyName="rotation"
            android:valueFrom="0"
            android:valueTo="360"
            android:valueType="floatType" />
        <objectAnimator
            android:duration="3000"
            android:propertyName="alpha"
            android:valueFrom="1"
            android:valueTo="0"
            android:valueType="floatType" />
        <objectAnimator
            android:duration="3000"
            android:propertyName="alpha"
            android:valueFrom="0"
            android:valueTo="1"
            android:valueType="floatType" />

    </set>
</set>

首先是不同时播放动画的嵌套
其次是同时播放的动画放到Set中
ordering:together动画同时执行 sequentially:分先后顺序的执行

将动画设置到控件上

Animator animator=AnimatorInflater.loadAnimator(this,R.animator.set_animator);
        animator.setTarget(set_xml_iv);
        animator.start();

动画的监听事件

以透明动画为例

animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                Log.d("TAG", "onAnimationStart");
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                Log.d("TAG", "onAnimationEnd");

            }

            @Override
            public void onAnimationCancel(Animator animation) {
                Log.d("TAG", "onAnimationCancel");

            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                Log.d("TAG", "onAnimationRepeat");

            }
        });

这里写图片描述

ViewPropertyAnimator

它用法也是非常的简单,和之前所学的属性动画有所不同,它是出现在3.1系统中,它被称作是属性系列的收尾部分
大家都知道属性动画已经不仅仅可以是现在View中进行设置(但是大多数应用场景都是View)Android开发团队也意识到了这一点,所以专门开发了一个专门操作于View的属性动画

下面是实现的效果

这里写图片描述

这里有三个动画效果–平移 旋转 透明度

//这个默认的是一个加速差值器
        textView.animate().alpha(0f).setDuration(3000);
        textView.animate().x(200f).y(200f).setDuration(3000);
     textView.animate().rotation(360).setDuration(3000).setInterpolator(new LinearInterpolator());

textView是添加动画的控件,直接调用控件对象的animate()方法在 . 属性值就可以进行动画的设置
是不是灰常简单呢

而下一篇就是一个经典案例购物车动画案例
敬请期待~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值