属性动画:基本使用和组合动画

今天道长说一下属性动画。毕竟现在手机app上基本上都会有动画的存在,像一些界面的切换,加载等等。属性动画是在Android3.0引入的,在此之前,帧动画和补间动画一起雄霸天下,那时的动画还不怎么复杂和炫酷,直到属性动画的出现让一些疯狂的产品经理在app中大量的添加动画甚至组合动画的需求……

一、三种动画

帧动画(frame-by-frame animation):顾名思义就是将一个完整的动画拆分成一张张单独的图片,然后再将它们连贯起来进行播放,类似于动画片的工作原理。
补间动画(tweened animation):则是可以对View进行一系列的动画操作,包括淡入淡出、缩放、平移、旋转四种。

  • 补间动画有两个缺陷:
    1.补间动画只能够作用在承自View的组件上的,不可对非View的对象进行操作。
    2.补间动画不对控件原有属性改变,也就是说View的淡入淡出、缩放、平移、旋转四种动画执行完,该View的位置,颜色,大小等等属性都没有改变。

属性动画(property animation):功能非常强大,弥补了之前补间动画的一些缺陷,几乎是可以完全替代掉补间动画

二、属性动画

补间动画和帧动画的出现比较早了,有很多功能的实现都已经被属性动画替代,这里道长就不过多讲关于补间动画和帧动画的内容了。

1.ObjectAnimator

对一个View进行动画操作,ObjectAnimator是我们最常接触到的类,可以直接对任意对象的任意属性进行动画操作

  • 透明度
    TextView在5秒内从常规变换成全透明,再从全透明变换成常规:
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f); 
animator.setDuration(5000); 
animator.start();
  • 旋转
    TextView在5秒内进行一次360度的旋转:
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f); 
animator.setDuration(5000); 
animator.start();
  • 平移
    TextView在5秒内先向左移出屏幕,然后再移动回来:
float curTranslationX = textview.getTranslationX(); 
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX", curTranslationX, -500f, curTranslationX); 
animator.setDuration(5000); 
animator.start();

这里道长调用了TextView的getTranslationX()方法来获取到当前TextView的translationX的位置,然后ofFloat()方法的第二个参数传入”translationX”告诉TextView要水平移动,紧接着后面三个参数用于告诉系统TextView应该怎么移动

  • 缩放
    TextView5秒内在垂直方向上放大3倍再还原,就可以这样写:
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f); 
animator.setDuration(5000); 
animator.start();

ObjectAnimator中的常用方法:

  • setStartDelay() - 设置动画延迟播放的时间
  • setRepeatCount() - 设置动画循环播放的次数
  • setRepeatMode() - 设置动画循环播放的模式,循环模式包括RESTART和REVERSE两种,分别表示重新播放和倒序播放。

2.XML编写动画

除了使用代码动态编写动画外还可以使用xml编写动画,使用xml编写的动画复用率比较高,可以大大减少app的体量,当然有利有弊,使用xml编写动画要比代码编写要慢,而且没有代码编写灵活。
要使用xml编写动画,首先要在res目录下面新建一个anim文件夹,所有属性动画的XML文件都应该存放在这个文件夹当中。然后在XML文件中我们一共可以使用如下三种标签:

  <animator> - 对应代码中的ValueAnimator
  <objectAnimator> - 对应代码中的ObjectAnimator
  <set> - 对应代码中的AnimatorSet

假如要实现一个从0到100平滑过渡的动画,在XML当中就可以这样写:

<animator xmlns:android="http://schemas.android.com/apk/res/android" 
    android:valueFrom="0" 
    android:valueTo="100" 
    android:valueType="intType"/>

如果将一个视图的alpha属性从1变成0,就可以这样写:

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

也可以这样写:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fromAlpha="1.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toAlpha="0.0" />

还可以这样写:

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

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fromAlpha="1.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toAlpha="0.0" />

</set>

然后在代码中调用即可:

Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim); 
animator.setTarget(view); 
animator.start();

3.调用View的方法编写动画

虽然TextView中没有alpha之类的属性,但是 ObjectAnimator内部的工作机制并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的get和set方法。所以我们也可以使用api编写动画。

        view.setRotation(360*fraction);//设置旋转的角度
//      view.setRotationX(360*fraction);//设置围绕x轴旋转的角度
//      view.setRotationY(360*fraction);//设置围绕Y轴旋转的角度

4.调用NineOldAndroid的方法编写动画

属性动画是Android3.0引入的,如果在Android3.0之前的系统上想要使用属性动画就要使用NineOldAndroid将3.0之后的属性动画和view相关的方法兼容到了3.0之前。

//      使用NineOldAndroid中的方法
//      ViewHelper.setRotation(redView, 360*fraction);//设置旋转的角度
        ViewHelper.setScaleX(redView, 1+fraction*0.5f);
        ViewHelper.setScaleY(redView, 1+fraction*0.5f);

总之实现的方法还是比较多的。

三、组合动画

1.代码编写

上面的就是属性动画独立执行的代码,但是独立的动画能够实现的视觉效果毕竟是相当有限的,因此将多个动画组合到一起播放就显得尤为重要。实现组合动画功能主要需要借助AnimatorSet这个类以及其中的四个方法:

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

有了这四个方法,就可以让我们的动画按照逻辑执行了,比如说我们想要让TextView先从屏幕外移动进屏幕,然后开始旋转360度,旋转的同时进行淡入淡出操作,就可以这样写:

ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f); 
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f); 
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f); 
AnimatorSet animSet = new AnimatorSet(); 
animSet.play(rotate).with(fadeInOut).after(moveIn); 
animSet.setDuration(5000); 
animSet.start();

这是一种比较常见的用法,我们也可以这么使用:

public void propertyValuesHolder(View view) {
    PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);
    PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
    PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
    ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY, pvhZ).setDuration(1000).start();
}

2.xml编写

当然我们也可以使用xml编写组合动画:

<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially" > 
    <objectAnimator 
        android:duration="2000"
        android:propertyName="translationX"
        android:valueFrom="-500"
        android:valueTo="0"
        android:valueType="floatType" > 
    </objectAnimator> 
    <set android:ordering="together" > 
        <objectAnimator 
            android:duration="3000"
            android:propertyName="rotation"
            android:valueFrom="0"
            android:valueTo="360"
            android:valueType="floatType" > 
        </objectAnimator> 
        <set android:ordering="sequentially" > 
            <objectAnimator 
                android:duration="1500"
                android:propertyName="alpha"
                android:valueFrom="1"
                android:valueTo="0"
                android:valueType="floatType" > 
            </objectAnimator> 
            <objectAnimator 
                android:duration="1500" 
                android:propertyName="alpha"
                android:valueFrom="0" 
                android:valueTo="1"
                android:valueType="floatType" > 
            </objectAnimator> 
        </set> 
    </set> 
</set>

选择使用代码编写还是使用xml编写主要看需求了,如果产品需求的复用可能性比较大就用xml,其他的看心情。

四、Animator监听器

一般在动画执行的时候或者动画执行完要去执行逻辑代码,这时候我们就希望可以监听到动画的各种事件,比如动画何时开始,何时结束。
我们可以添加一个监听器来实现监听,如下所示:

anim.addListener(new AnimatorListener() { 
    @Override 
    public void onAnimationStart(Animator animation) { 
    } 
    @Override 
    public void onAnimationRepeat(Animator animation) { 
    } 
    @Override 
    public void onAnimationEnd(Animator animation) { 
    } 
    @Override 
    public void onAnimationCancel(Animator animation) { 
    } 
});

监听接口里的这四个方法就不多说了,如果不想每次都重写这四个方法还可以实现监听适配器这个类,代码如下:

anim.addListener(new AnimatorListenerAdapter() { 
    @Override 
    public void onAnimationEnd(Animator animation) { 
    } 
});

属性动画的基本使用和组合动画就说到这里,一般的需求也就用到这么多,下次道长在说一下属性动画的高级应用。希望这篇博客能为你提供一些帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值