Android实现动画组合的四种方式

先上动图,本文介绍实现下面动图中组合动画的四种方式
在这里插入图片描述

方式一:视图动画之AnimationSet

  • xml方式实现
<?xml version="1.0" encoding="utf-8"?>
<set
    android:fillAfter="true"
    android:duration="3000"
    android:shareInterpolator="@android:anim/accelerate_decelerate_interpolator"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <!--透明度从无到有-->
    <alpha android:fromAlpha="0"
        android:toAlpha="1"/>

    <!--旋转两圈-->
    <rotate
        android:pivotY="50%"
        android:pivotX="50%"
        android:fromDegrees="0"
        android:toDegrees="720"/>

    <!--放大三倍-->
    <scale android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="0.1"
        android:fromYScale="0.1"
        android:toXScale="3"
        android:toYScale="3"/>

    <!--平移至中间位置-->
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="35%p"
        android:toYDelta="42.5%p"/>

</set>

   //1.通过xml方式引入动画
       Animation animationSet = AnimationUtils.loadAnimation(this,R.anim.anim_set_pic);
        //设置动画时长为3秒
        animationSet.setDuration(3000);
        //设置插值器为先加速再减速
        animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
        //动画完成后保持位置
        animationSet.setFillAfter(true);
        //开始动画
        ibSagiri.startAnimation(animationSet);
  • 代码方式实现
      
        //2.通过代码生成方式
        AnimationSet animationSet = new AnimationSet(true); //true表示共用同一个插值器
        //透明度从0至1
        AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
        //旋转两圈
        RotateAnimation rotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        //放大三倍
        ScaleAnimation scaleAnimation = new ScaleAnimation(0.1f, 3, 0.1f, 3, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        //平移距离x方向为父控件宽的35%,y方向为父控件高的42.5%
        TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_PARENT, 0.35f, Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_PARENT, 0.425f);
        animationSet.addAnimation(alphaAnimation);
        animationSet.addAnimation(rotateAnimation);
        animationSet.addAnimation(scaleAnimation);
        animationSet.addAnimation(translateAnimation);
        //设置动画时长为3秒
        animationSet.setDuration(3000);
        //设置插值器为先加速再减速
        animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
        //动画完成后保持位置
        animationSet.setFillAfter(true);
        //开始动画
        ibSagiri.startAnimation(animationSet);

方式二:属性动画1之AnimatorSet

  //生成一个透明度变化的属性动画对象
        ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(ibSagiri, "alpha", 0, 0.2f, 0.5f, 1);
        //旋转两圈的动画
        ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat(ibSagiri, "rotation", 0, 360, 540, 720);
        //X轴移动35%父视图的长度
        ObjectAnimator translationXAnimator = ObjectAnimator.ofFloat(ibSagiri, "translationX", 0, clParent.getWidth() * 0.35f);
        //Y轴移动42.5%父视图的长度
        ObjectAnimator translationYAnimator = ObjectAnimator.ofFloat(ibSagiri, "translationY", 0, clParent.getHeight() * 0.425f);
        //XY方向都放大3倍
        ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(ibSagiri, "scaleX", 0, 1, 2, 3);
        ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(ibSagiri, "scaleY", 0, 1, 2, 3);

        //生成一个animatorSet对象
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(3000);
        animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
        //播放多条动画
        animatorSet.playTogether(alphaAnimator, rotationAnimator, translationXAnimator, translationYAnimator, scaleXAnimator, scaleYAnimator);
        animatorSet.start();

方式三:属性动画2之PropertyValuesHolder

        //生成一个透明度变化的valuesHolder,其他同上
        PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofFloat("alpha", 0, 0.2f, 0.5f, 1);
        PropertyValuesHolder rotationHolder = PropertyValuesHolder.ofFloat("rotation", 0, 360, 540, 720);
        PropertyValuesHolder translationXHolder = PropertyValuesHolder.ofFloat("translationX", 0, clParent.getWidth() * 0.35f);
        PropertyValuesHolder translationYHolder = PropertyValuesHolder.ofFloat("translationY", 0, clParent.getHeight() * 0.425f);
        PropertyValuesHolder scaleXHolder = PropertyValuesHolder.ofFloat("scaleX", 0, 1, 2, 3);
        PropertyValuesHolder scaleYHolder = PropertyValuesHolder.ofFloat("scaleY", 0, 1, 2, 3);
        ////利用多个Holder生成一个ObjectAnimator对象
        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(ibSagiri, alphaHolder, rotationHolder, translationXHolder, translationYHolder, scaleXHolder, scaleYHolder);
        //设置动画时间
        animator.setDuration(3000);
        //设置插值器
        animator.setInterpolator(new AccelerateDecelerateInterpolator());
        animator.start();

方式四:ViewPropertyAnimator

       ibSagiri.animate()
//                .alpha(1) 使用该种方式无法实现透明度的变化
                .rotation(720)
                .translationX(clParent.getWidth() * 0.35f).translationY(clParent.getHeight() * 0.425f)
                .scaleX(3).scaleY(3)
                .setDuration(3000)
                .setInterpolator(new AccelerateDecelerateInterpolator())
        ;

该方式有一个缺馅,无法实现透明度从0到1的变化。

关于ViewPropertyAnimator的小知识:
ViewPropertyAnimator并没有像ObjectAnimator一样使用反射或者JNI技术;而ViewPropertyAnimator会根据预设的每一个动画帧计算出对应的所有属性值,并设置给控件,然后调用一次invalidate()函数进行重绘,从而解决了在使用ObjectAnimator时每个属性单独计算、单独重绘的问题。所以ViewPropertyAnimator相对于ObjectAnimator和组合动画,性能有所提升。
-----摘自启舰《Android自定义控件开发入门与实战》P153

Tips:动画种类知识

Android中的动画共分为两大类,视图动画(ViewAnimation)和属性动画(PropertyAnimator)

  • 视图动画:只是视觉上移动控件,实际控件放置区域依然不变
  • 属性动画:以改变控件属性的方式来达到做动画的效果,实际控件放置区域会随动画而做改变。

总结如下图所示
在这里插入图片描述

发布了92 篇原创文章 · 获赞 68 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/pigdreams/article/details/85390394