动画必须有(一): 属性动画浅谈

简介: 目录前言ObjectAnimator的初步使用用AnimatorSet进行动画混合将动画写在xml中动画监听ViewPropertyAnimator上手最后前言官方文档传送门属性动画是非常非常好用的, 谷歌自己都说这是一个强大的框架.

目录

  • 前言
  • ObjectAnimator的初步使用
  • 用AnimatorSet进行动画混合
  • 将动画写在xml中
  • 动画监听
  • ViewPropertyAnimator上手
  • 最后

前言

官方文档传送门

属性动画是非常非常好用的, 谷歌自己都说这是一个强大的框架. 那今天就来了解一下它.

ObjectAnimator的初步使用

属性动画最大的特点就是可以让任何Object动起来, 我先给个小栗子, 大家感受一下.

TextView tvTest = (TextView) findViewById(R.id.tv_test);
float curTranslationY = tvTest.getTranslationY();
ObjectAnimator animator
        = ObjectAnimator.ofFloat(tvTest, "translationY",
        curTranslationY, curTranslationY + 100f);
animator.setDuration(2000);
animator.start();
栗子
栗子

属性动画有个很重要的点就是说, 动画过后, 控件本身真的就变换了, 而不单单是绘制出了效果.

然后这里ofFloat()函数的第一个参数自然是控件了, 第二个参数是可以填入很多的, 比如"alpha", "rotation", 到底有多少, 大家可以移步官方文档. 然后后面的参数根据第二个参数来, 可多个, 这里可能说的不太清晰, 所以我们再来一个小栗子.

TextView tvTest = (TextView) findViewById(R.id.tv_test);
ObjectAnimator animator
        = ObjectAnimator.ofFloat(tvTest, "alpha",
        1f, 0f, 1f, 0f, 1f, 0f, 1f);
animator.setDuration(2000);
animator.start();
又见栗子
又见栗子

用AnimatorSet进行动画混合

一般来说, 让人感觉舒服的动画都不会是单一变换的动画, 肯定要各种动画混合一起, 来达到某种效果. 我这里进行一些混合的尝试, 顺便再展示几种动画.

// 垂直移动
float curTranslationY = tvTest.getTranslationY();
ObjectAnimator translationY
        = ObjectAnimator.ofFloat(tvTest, "translationY",
        curTranslationY, curTranslationY + 500f);

ObjectAnimator scaleY = ObjectAnimator.ofFloat(tvTest, "scaleY", 1f, 5f, 1f);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(tvTest, "scaleX", 1f, 5f, 1f);

AnimatorSet animSet = new AnimatorSet();
animSet.play(scaleY).with(scaleX).after(translationY);
animSet.setDuration(2000);
animSet.start();
混合动画
混合动画

这里就是将垂直移动动画, 水平缩放垂直缩放混合在一起, 大家肯定发现了, play(), with(), after()这几个函数.

  • after(Animator anim) after中的动画先执行, 之后才是play中的动画.
  • after(long delay) after中设置时间, 那么play中的动画会根据时间延迟执行.
  • before(Animator anim) before中的动画后执行, play中的先执行.
  • with(Animator anim) play中的动画和with中的一同执行.
  • playTogether() 中间可以放入要一起执行的全部动画, 之后不可接after(), before()这些函数. 来个小栗子.
AnimatorSet animSet = new AnimatorSet();
animSet.playTogether(translationY, scaleX, scaleY);
animSet.setDuration(2000);
animSet.start();
动画混合
动画混合

将动画写在xml中

写在xml中的好处不言而喻了, 复用性极强. 直接贴代码了, 很好理解的.

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">

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

    <set android:ordering="sequentially">
        <objectAnimator
            android:duration="1000"
            android:propertyName="rotation"
            android:valueFrom="0"
            android:valueTo="360"
            android:valueType="floatType" />

        <set android:ordering="together">
            <objectAnimator
                android:duration="1000"
                android:propertyName="scaleX"
                android:valueFrom="1"
                android:valueTo="5"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="1000"
                android:propertyName="scaleY"
                android:valueFrom="1"
                android:valueTo="5"
                android:valueType="floatType" />
        </set>
    </set>
</set>

然后使用如下代码调用xml动画.

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(getApplicationContext(), R.animator.anim_set);
set.setTarget(tvTest);
set.start();

动画监听

动画监听是很有必要知道的, 我们是在做软件, 不是在做电影, 不能让它一个劲播下去. 先看一个比较全面的监听.

translationY.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
        
    }

    @Override
    public void onAnimationEnd(Animator animation) {

    }

    @Override
    public void onAnimationCancel(Animator animation) {

    }

    @Override
    public void onAnimationRepeat(Animator animation) {

    }
});

这个很麻烦啦, 所以有适配版本的监听. 如果你用Android Studio它会弹出框让你选择.

选择复写的函数
选择复写的函数
translationY.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
    }
});

ViewPropertyAnimator上手

属性动画是谷歌在android3.0引入的, 而ViewPropertyAnimator则是3.1引入的, 这个ViewPropertyAnimator绝对可以说是个磨人的小妖精, 它绝对会让你爱上属性动画的, 看个栗子:

tvTest.animate().translationY(curTranslationY + 500)
        .scaleX(5).scaleY(5)
        .setDuration(1000);
ViewPropertyAnimator栗子
ViewPropertyAnimator栗子

用ViewPropertyAnimator的目的就是精简代码以及快速实现, 想要处理一些复杂的动画, 还是要用上一篇说的内容慢慢来的(滑稽脸).
我们稍微修改一点代码, 看看新效果.

tvTest.animate().translationYBy(250)
        .scaleX(5).scaleY(5)
        .setDuration(1000);
By不By
By不By

其实可以看函数就看得出来意思了, 不加By代表直接移动某个值, 加了By代表在原有基础上移动某个值.
好, 我们再来看一个及其经典的代码, 可以完美展现出ViewPropertyAnimator的精简好用:

view.animate()// 获取ViewPropertyAnimator对象
        // 动画持续时间
        .setDuration(5000)

        // 透明度
        .alpha(0)
        .alphaBy(0)

        // 旋转
        .rotation(360)
        .rotationBy(360)
        .rotationX(360)
        .rotationXBy(360)
        .rotationY(360)
        .rotationYBy(360)

        // 缩放
        .scaleX(1)
        .scaleXBy(1)
        .scaleY(1)
        .scaleYBy(1)

        // 平移
        .translationX(100)
        .translationXBy(100)
        .translationY(100)
        .translationYBy(100)
        .translationZ(100)
        .translationZBy(100)

        // 更改在屏幕上的坐标
        .x(10)
        .xBy(10)
        .y(10)
        .yBy(10)
        .z(10)
        .zBy(10)

        // 插值器
        .setInterpolator(new BounceInterpolator())//回弹
        .setInterpolator(new AccelerateDecelerateInterpolator())//加速再减速
        .setInterpolator(new AccelerateInterpolator())//加速
        .setInterpolator(new DecelerateInterpolator())//减速
        .setInterpolator(new LinearInterpolator())//线性

        // 动画延迟
        .setStartDelay(1000)

        //是否开启硬件加速
        .withLayer()

        // 监听
        .setListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        })

        .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
            }
        })

        .withEndAction(new Runnable() {
            @Override
            public void run() {
            }
        })
        .withStartAction(new Runnable() {
            @Override
            public void run() {
            }
        });

所以日常动画用它就足够了.


最后

有了属性动画, 界面就不会很死板了. 而且由于属性动画的特性, 让它可以完成动画部分的事, 甚至可以完成很多界面交互上的事. 喜欢记得点赞或者关注我哦.


目录
相关文章
|
4天前
|
前端开发
Filp动画
Filp动画基于First、Last、Inverse、Play四步实现复杂前端动画效果。首先记录元素初始位置,接着记录目标位置,然后使用transform属性将元素逆向平移回初始位置,最后通过移除transform并添加transition属性实现平滑动画效果。这是一种高效解决CSS不支持过渡动画问题的方法。
|
1月前
|
JavaScript 开发者
HarmonyNext动画大全03-帧动画
HarmonyNext动画大全03-帧动画
19 2
|
存储 文件存储 云计算
不瞒了,我们和追光动画有一个《杨戬》!
不瞒了,我们和追光动画有一个《杨戬》!
194 0
|
图形学
unity动画之帧动画使用
使用unity实现lol寒冰帧动画
unity动画之帧动画使用
属性动画 - CAAnimationDelegate
属性动画 - CAAnimationDelegate
134 0
|
前端开发
动画
动画
139 0
|
前端开发
2、CSS动画——拳皇动画实现
2、CSS动画——拳皇动画实现
124 0
2、CSS动画——拳皇动画实现
|
Android开发 内存技术
Android动画(帧动画、补间动画、属性动画)讲解
帧动画:是一种常见的动画形式(Frame By Frame),其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。 补间动画:指的是做FLASH动画时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动; 属性动画:帧动画与补间动画实现了对View进行移动、缩放、旋转和淡入淡出的效果。但对于android开发师来说是不够的,同时移动、缩放、旋转和淡入淡出的效果也不再只是一种视觉上的动画效果了。所以从Android 3.0版本开始,系统给我们提供了一种全新的动画模式,属性动画(property animation)。
341 0
Android动画(帧动画、补间动画、属性动画)讲解
|
前端开发 图形学 Python
动画系统之2D动画
动画系统之2D动画
181 0
动画系统之2D动画
|
存储 图形学
动画系统中的基础动画
动画系统中的基础动画
175 0
动画系统中的基础动画