多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 1. 属性动画 属性动画可以作用于任意对象,而不仅仅局限在`View`。同时也支持更多的动画,而不只是四种动画效果。 * 动画默认间隔`300ms`,默认帧率`10ms/帧`。 * 但是是`API 11`(对应`Android 3.0`)之后才支持的,所以如果要兼容之前的版本还需要做处理。 * 在属性动画中,比较常见的动画类有:`ValueAnimator`、`ObjectAnimator`和`AnimatorSet`。`ObjectAnimator`继承自`ValueAnimator`。 # 2. 简单使用(动态代码方式) ## 2.1 平移 将按钮向下平移高度个距离: ~~~ btn.setOnClickListener { ObjectAnimator.ofFloat(it, "translationY", 1f*it.height) .start() } ~~~ ## 2.2 渐变 将按钮的背景色设置为一个渐变,重复: ~~~ btn.setOnClickListener { val colorAnim = ObjectAnimator.ofInt( it, "backgroundColor", 0xFFFF8080.toInt(), 0xFF8080FF.toInt() ) colorAnim.apply { duration = 500 repeatCount = ValueAnimator.INFINITE setEvaluator(ArgbEvaluator()) repeatMode = ValueAnimator.REVERSE } colorAnim.start() } ~~~ ## 2.3 动画集 ~~~ // true,代表使用默认的interpolator val animationSet = AnimationSet(true) // 透明度 0-1 val alphaAnimation = AlphaAnimation(0f, 1f) // 旋转 val rotateAnimation = RotateAnimation(0f, 90f) // 放大 val scaleAnimation = ScaleAnimation(1f, 1.2f, 1f, 1.2f) animationSet.apply { addAnimation(alphaAnimation) addAnimation(rotateAnimation) addAnimation(scaleAnimation) duration = 5000 interpolator = AccelerateDecelerateInterpolator() fillAfter = true } btn.setOnClickListener { it.startAnimation(animationSet) } ~~~ ## 2.4 对任意属性修改 值得注意的是,在`View`动画中只能完成简单的平移、旋转、缩放和透明度变换。如果我们希望修改一个按钮的宽度,那么他是做不到的。这里我们可以使用属性动画轻松做到: ~~~ val animator = ObjectAnimator.ofInt(btn, "width", 700) btn.setOnClickListener { animator.start() } ~~~ 对于`TextView`,我们做类似的处理: ~~~ <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:textColor="@color/black" android:textSize="24sp" android:background="@color/teal_200" android:gravity="center" /> ~~~ 然后关联: ~~~ val textViewAnimator = ObjectAnimator.ofInt(textView, "width", 700) textView.setOnClickListener { textViewAnimator.start() } ~~~ 同样的也有对应的效果。 # 3. xml方式 文件需要定义在`res/animator`目录下,比如`attranimator01.xml`: ~~~ <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially" > <objectAnimator android:propertyName="backgroundColor" android:duration="2000" android:valueFrom="0xffffff00" android:valueTo="0xff00ff00" android:valueType="intType" android:repeatCount="infinite" android:repeatMode="reverse" /> </set> ~~~ 然后关联: ~~~ val loadAnimator = AnimatorInflater.loadAnimator(this, R.animator.attranimator01) loadAnimator.setTarget(btn) btn.setOnClickListener { loadAnimator.start() } ~~~ # 4. ValueAnimator 注意到上面提到了`ObjectAnimator`继承自`ValueAnimator`,那么为什么我们前面没有使用`ValueAnimator`,而只涉及到`ObjectAnimator`类?因为`ValueAnimator`只是对一个值做动画,如果我们将`ValueAnimator`直接用来做动画没有任何效果产生,因为还没有对应的修改对象的属性。 那么如果我们能够监听到`ValueAnimator`中值得变化,然后我们将其值应用到对应的对象的属性上,那么就回产生对应的效果。 # 5. 对比 ## anim文件夹 `anim`文件夹下存放补间动画(即`View`动画);`xml`文件里只有`scale`、`rotate`、`translate`、`alpha`、`set`五个标签, 使用方法: 1. 加载动画:`animation = AnimationUtils.loadAnimation(R.anim.xxx)` 2. 设置动画:`mView.setAnimation(animation)` 3. 开启动画:`mView.startAnimation()` ## animator文件夹 `animator`文件夹下存放属性动画,`xml`文件里有`animator`、`objectAnimator`、`set`三个标签, 使用方法: 1. 加载动画:`animation = AnimatorInflater.loadAnimator(R.animator.xxx)` 2. 设置动画:`animation.setTarget(mView)` 3. 开启动画:`animation .start()` # 6. 注意 在属性动画中,有一种动画为无限循环动画,这类动画需要在`Activity`退出时及时停止,否则可能导致当前`Activity`内存得不到释放,造成内存泄漏。且对于属性动画做一系列变换后,事件触发位置在控件位置;但是`View`动画变换后,还是原来位置会触发事件。这是因为属性动画在任何属性发生变化后,`View`都会自动调用`invalidate()`来绘制。而`View`所做的简单的平移、旋转、透明度和缩放仅仅是作用在视图,其位置属性不变。