天天看点

Android属性动画 ObjectAnimatorObjectAnimator实战-心跳动画参考资料

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/118709616

本文出自【赵彦军的博客】

文章目录

  • ObjectAnimator
  • 实战-心跳动画
  • 参考资料

ObjectAnimator

public final class ObjectAnimator extends ValueAnimator {
...
}
           

ObjectAnimator

继承

ValueAnimator

, 所以

ObjectAnimator

拥有

ValueAnimator

一切特性。

相比于

ValueAnimator

ObjectAnimator

可能才是我们最常接触到的类,因为

ValueAnimator

只不过是对值进行了一个平滑的动画过渡,但我们实际使用到这种功能的场景好像并不多。而

ObjectAnimator

则就不同了,它是可以直接对任意对象的任意属性进行动画操作的,比如说

View

alpha

属性。

不过虽说

ObjectAnimator

会更加常用一些,但是它其实是继承自

ValueAnimator

的,底层的动画实现机制也是基于ValueAnimator来完成的,因此

ValueAnimator

仍然是整个属性动画当中最核心的一个类。那么既然是继承关系,说明

ValueAnimator

中可以使用的方法在

ObjectAnimator

中也是可以正常使用的,它们的用法也非常类似,这里如果我们想要将一个

TextView

在5秒中内从常规变换成全透明,再从全透明变换成常规,就可以这样写:

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();
           

可以看到,我们还是调用了

ofFloat()

方法来去创建一个

ObjectAnimator

的实例,只不过

ofFloat()

方法当中接收的参数有点变化了。这里第一个参数要求传入一个

object

对象,我们想要对哪个对象进行动画操作就传入什么,这里我传入了一个

textview

。第二个参数是想要对该对象的哪个属性进行动画操作,由于我们想要改变

TextView

的不透明度,因此这里传入

"alpha"

。后面的参数就是不固定长度了,想要完成什么样的动画就传入什么值,这里传入的值就表示将

TextView

从常规变换成全透明,再从全透明变换成常规。之后调用

setDuration()

方法来设置动画的时长,然后调用

start()

方法启动动画,效果如下图所示:

Android属性动画 ObjectAnimatorObjectAnimator实战-心跳动画参考资料

学会了这一个用法之后,其它的用法我们就可以举一反三了,那比如说我们想要将

TextView

进行一次

360度

的旋转,就可以这样写:

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
animator.setDuration(5000);
animator.start();
           

可以看到,这里我们将第二个参数改成了

"rotation"

,然后将动画的初始值和结束值分别设置成

0和360

,现在运行一下代码,效果如下图所示:

Android属性动画 ObjectAnimatorObjectAnimator实战-心跳动画参考资料

那么如果想要将TextView先向左移出屏幕,然后再移动回来,就可以这样写:

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

应该怎么移动,现在运行一下代码,效果如下图所示:

Android属性动画 ObjectAnimatorObjectAnimator实战-心跳动画参考资料

然后我们还可以

TextView

进行缩放操作,比如说将

TextView

在垂直方向上放大3倍再还原,就可以这样写:

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f);
animator.setDuration(5000);
animator.start();
           

这里将ofFloat()方法的第二个参数改成了"scaleY",表示在垂直方向上进行缩放,现在重新运行一下程序,效果如下图所示:

Android属性动画 ObjectAnimatorObjectAnimator实战-心跳动画参考资料

到目前为止,

ObjectAnimator

的用法还算是相当简单吧,但是我相信肯定会有不少朋友现在心里都有同样一个疑问,就是

ofFloat()

方法的第二个参数到底可以传哪些值呢?

目前我们使用过了

alpha

rotation

translationX

scaleY

这几个值,分别可以完成淡入淡出、旋转、水平移动、垂直缩放这几种动画,那么还有哪些值是可以使用的呢?

其实这个问题的答案非常玄乎,就是我们可以传入任意的值到

ofFloat()

方法的第二个参数当中。任意的值?相信这很出乎大家的意料吧,但事实就是如此。因为

ObjectAnimator

在设计的时候就没有针对于

View

来进行设计,而是针对于任意对象的,它所负责的工作就是不断地向某个对象中的某个属性进行赋值,然后对象根据属性值的改变再来决定如何展现出来。

那么比如说我们调用下面这样一段代码:

其实这段代码的意思就是

ObjectAnimator

会帮我们不断地改变

textview

对象中

alpha

属性的值,从1f变化到0f。然后

textview

对象需要根据

alpha

属性值的改变来不断刷新界面的显示,从而让用户可以看出淡入淡出的动画效果。

那么

textview

对象中是不是有

alpha

属性这个值呢?

没有,不仅

textview

没有这个属性,连它所有的父类也是没有这个属性的!

这就奇怪了,

textview

当中并没有alpha这个属性,

ObjectAnimator

是如何进行操作的呢?其实

ObjectAnimator

内部的工作机制并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的

get和set

方法,因此alpha属性所对应的

get和set

方法应该就是:

public void setAlpha(float value);
public float getAlpha();
           

那么

textview

对象中是否有这两个方法呢?确实有,并且这两个方法是由

View

对象提供的,也就是说不仅

TextView

可以使用这个属性来进行淡入淡出动画操作,任何继承自

View

的对象都可以的。

既然

alpha

是这个样子,相信大家一定已经明白了,前面我们所用的所有属性都是这个工作原理,那么View当中一定也存在着

setRotation()

getRotation()

setTranslationX()

getTranslationX()

setScaleY()

getScaleY()

这些方法,不信的话你可以到View当中去找一下。

实战-心跳动画

先上效果图:

Android属性动画 ObjectAnimatorObjectAnimator实战-心跳动画参考资料

自定义 View

/**
 * @author : zhaoyanjun
 * @time : 2021/7/13
 * @desc :
 */
class MyView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {

    private var radius = 10f  //圆的半径
        set(value) {
            field = value
            invalidate()
        }

    private val paint = Paint()

    init {
        paint.color = Color.BLUE
        paint.textSize = 8f
        paint.isAntiAlias = true
        paint.style = Paint.Style.FILL
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        //绘制圆
        canvas?.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), radius, paint)
    }
}
           

有一点很重要的是,

radius

的 set 方法中需要调用

invalidate()

方法,才能够刷新

view

我们再看执行动画的部分

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var myView: MyView = findViewById(R.id.myView)
        
        //通过动画,不断的改变 radius 的值
        var objectAnimator =
            ObjectAnimator.ofFloat(myView, "radius", 200f, 500f, 200f)
        objectAnimator.duration = 600
        objectAnimator.interpolator = LinearInterpolator()
        objectAnimator.repeatCount = 20  //执行20次
        objectAnimator.start()
    }
}

           

参考资料

  • Android属性动画完全解析(上),初识属性动画的基本用法