加深学习|android属性动画(Kotlin)

大佬详细讲解属性动画: https://www.jianshu.com/p/2412d00a0ce4
另一位大佬的视频讲解,短小精悍: https://www.imooc.com/video/5447
两个概念:
插值器(Interpolator) 决定 值 的变化模式(匀速、加速blabla)
估值器(TypeEvaluator) 决定 值 的具体变化数值
插值器:
加深学习|android属性动画(Kotlin)
文章图片

1. ValueAnimator类:
是什么: 属性动画机制中 最核心的一个类,通过不断控制 值 的变化,再不断 手动 赋给对象的属性,从而实现动画效果。如图下
它的方法:

ValueAnimator.ofInt(int values)//整型估值器 ValueAnimator.ofFloat(float values) //浮点型估值器 ValueAnimator.ofObject(int values)//对象型估值器

怎么办:
通过整型估值器来试试:实现的是在2秒内让数值从0变化到300
如果在addUpdateListener方法中将变化的数值付给控件的属性 就可以为控件添加上动画了
PS:把数值赋值给属性后,一定要调用该控件的requestLayout()方法,不然动画不会显示
val valueAnimator = ValueAnimator.ofInt(0,300)//数值从0到300 valueAnimator.duration = 2000//时间2秒 valueAnimator.addUpdateListener(object : ValueAnimator.AnimatorUpdateListener{ override fun onAnimationUpdate(animation: ValueAnimator) { Log.e("AA","数值变化:${animation.animatedValue}") } }) valueAnimator.start()//启动

2.ObjectAnimator类:
是什么:
直接对对象的属性值进行改变操作,从而实现动画效果
如直接改变 View的 alpha 属性 从而实现透明度的动画效果
继承自ValueAnimator类,即底层的动画实现机制是基于ValueAnimator类
通过一个例子来了解:
实现效果:
加深学习|android属性动画(Kotlin)
文章图片

首先新建布局文件让它的布局为FrameLayout,边放上准备好的小圆点层叠放在一起:

然后就是activity中的代码了:
package com.example.administrator.myktnotepadimport android.animation.* import android.app.Activity import android.content.pm.ActivityInfo import android.os.Build import android.os.Bundle import android.view.View import android.view.Window import android.view.WindowManager import android.view.animation.AccelerateInterpolator import android.view.animation.BounceInterpolator import android.view.animation.OvershootInterpolator import android.widget.ImageView import android.widget.Toast import kotlinx.android.synthetic.main.activity_main.* import android.util.DisplayMetrics import android.util.Log import android.widget.AdapterViewAnimatorclass MainActivity : Activity(), View.OnClickListener { private var isOpen: Boolean = false private var width = 0 private var height = 0 override fun onClick(v: View) { when (v.id) { R.id.img -> { isOpen = if (!isOpen) { startAnim(); true } else { endAnim(); false } Toast.makeText(this, "点击了img", Toast.LENGTH_SHORT).show() } R.id.img1 -> Toast.makeText(this, "点击了1", Toast.LENGTH_SHORT).show() R.id.img2 -> Toast.makeText(this, "点击了2", Toast.LENGTH_SHORT).show() R.id.img3 -> Toast.makeText(this, "点击了3", Toast.LENGTH_SHORT).show() } }override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if (Build.VERSION.SDK_INT >= 21) { // 实现状态栏半透明 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) } img.setOnClickListener(this) img1.setOnClickListener(this) img2.setOnClickListener(this) img3.setOnClickListener(this) val manager = this.windowManager val outMetrics = DisplayMetrics() manager.defaultDisplay.getMetrics(outMetrics) width = outMetrics.widthPixels height = outMetrics.heightPixels}//动画 private fun startAnim() { val anim1 = ObjectAnimator.ofFloat(img1, View.TRANSLATION_X, 0f, height / 10f) val anim11 = ObjectAnimator.ofFloat(img1, View.TRANSLATION_Y, 0f, height / 10f)val anim2 = ObjectAnimator.ofFloat(img2, View.TRANSLATION_X, 0f, height / 10 * 1.5f)val anim3 = ObjectAnimator.ofFloat(img3, View.TRANSLATION_X, 0f, height / 10f) val anim33 = ObjectAnimator.ofFloat(img3, View.TRANSLATION_Y, 0f, -height / 10f)val anim = AnimatorSet() //anim.playSequentially(anim1, anim2, anim3) //anim.playTogether(anim1,anim2,anim3) anim.play(anim1).with(anim11) anim.play(anim2).after(anim1) anim.play(anim3).with(anim33).after(anim2) anim.duration = 1000 anim.interpolator = BounceInterpolator()//插值器有弹球效果 anim.addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) { super.onAnimationStart(animation) img.isEnabled = false }override fun onAnimationEnd(animation: Animator?) { super.onAnimationEnd(animation) img.isEnabled = true } }) anim.start()}private fun endAnim() { val anim1 = ObjectAnimator.ofFloat(img1, View.TRANSLATION_X, 0f) val anim11 = ObjectAnimator.ofFloat(img1, View.TRANSLATION_Y, 0f)val anim2 = ObjectAnimator.ofFloat(img2, View.TRANSLATION_X, 0f)val anim3 = ObjectAnimator.ofFloat(img3, View.TRANSLATION_X, 0f) val anim33 = ObjectAnimator.ofFloat(img3, View.TRANSLATION_Y, 0f)val anim = AnimatorSet() anim.play(anim1).with(anim11).with(anim2).with(anim3).with(anim33) anim.interpolator = AccelerateInterpolator()//插值器有起始加速结束减速效果 anim.duration = 1000 anim.addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) { super.onAnimationStart(animation) img.isEnabled = false }override fun onAnimationEnd(animation: Animator?) { super.onAnimationEnd(animation) img.isEnabled = true } }) anim.start() } }

代码可以直接拷贝使用
【加深学习|android属性动画(Kotlin)】我们来看一下代码动画实现的核心代码:
ObjectAnimator的方法:
// ObjectAnimator.ofFloat(,,...):这是ObjectAnimator的浮点型估值器, 一参:要加动画的对象; 二参:要改变哪个属性; 后面参数:是一个可填写一个至多个的参数,是你动画数值的变化, 写一个就是目标值, 写两个就是起始值和结束值, 写3个到多个,除了起点和结束中间都是动画持续时间中它会改变的值 val anim1 = ObjectAnimator.ofFloat(img1, View.TRANSLATION_X, 0f, height / 10f)

ObjectAnimator.ofFloat()第二个参数可以控制的属性(任意属性值!!):
加深学习|android属性动画(Kotlin)
文章图片

通过AnimatorSet实现多动画的组合:
方法:
组合动画的执行顺序:
anim.playSequentially(anim1, anim2, anim3) // 依次执行参数中的3个方法
anim.playTogether(anim1,anim2,anim3) // 一块执行参数中的3个方法
更加灵活的顺序:
anim.play(anim1).with(anim11) // anim1与anim11一块执行
anim.play(anim2).after(anim1) // anim2在anim1执行之后再执行
anim.play(anim3).with(anim33).after(anim2) // anim3和anim33会在anim2执行后在一块执行
val anim = AnimatorSet() //anim.playSequentially(anim1, anim2, anim3) //anim.playTogether(anim1,anim2,anim3) anim.play(anim1).with(anim11) anim.play(anim2).after(anim1) anim.play(anim3).with(anim33).after(anim2) anim.duration = 1000 anim.interpolator = BounceInterpolator()//插值器有弹球效果 anim.addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) { super.onAnimationStart(animation) img.isEnabled = false }override fun onAnimationEnd(animation: Animator?) { super.onAnimationEnd(animation) img.isEnabled = true } }) anim.start()

文章写的不好,主要为了个人的理解记忆,但是大佬写的很棒啊,你们可以去看大佬的链接!加油加油~哈哈

    推荐阅读