当前位置:网站首页>属性动画的使用和原理解析
属性动画的使用和原理解析
2022-08-02 03:27:00 【浮空over】
文章目录
前言
属性动画,顾名思义它是对于对象属性的动画。因此,所有补间动画的内容,都可以通过属性动画实现。
一、属性动画入门
首先我们来看看如何用属性动画实现上面补间动画的效果
private void RotateAnimation() {
ObjectAnimator anim = ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);
anim.setDuration(1000);
anim.start();
}
private void AlpahAnimation() {
ObjectAnimator anim = ObjectAnimator.ofFloat(myView, "alpha", 1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f);
anim.setRepeatCount(-1);
anim.setRepeatMode(ObjectAnimator.REVERSE);
anim.setDuration(2000);
anim.start();
}
这两个方法用属性动画的方式分别实现了旋转动画和淡入淡出动画,其中setDuration、setRepeatMode及setRepeatCount和补间动画中的概念是一样的。
可以看到,属性动画貌似强大了许多,实现很方便,同时动画可变化的值也有了更多的选择,动画所能呈现的细节也更多。
当然属性动画也是可以组合实现的
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(myView, "alpha", 1.0f, 0.5f, 0.8f, 1.0f);
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(myView, "scaleX", 0.0f, 1.0f);
ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(myView, "scaleY", 0.0f, 2.0f);
ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(myView, "rotation", 0, 360);
ObjectAnimator transXAnim = ObjectAnimator.ofFloat(myView, "translationX", 100, 400);
ObjectAnimator transYAnim = ObjectAnimator.ofFloat(myView, "tranlsationY", 100, 750);
AnimatorSet set = new AnimatorSet();
set.playTogether(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
// set.playSequentially(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
set.setDuration(3000);
set.start();
可以看到这些动画可以同时播放,或者是按序播放。
二、属性动画具体使用
1.步骤
创建objectAnimator
设置Interpolator(插值器)
设置Evaluator(估值器)
设置动画时长
开启动画
//透明度起始为1,结束时为0
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f);
animator.setDuration(1000);//时间1s
animator.start();
/* ofFloat中的参数: imageView:执行动画的View; "alpha":表示透明动画; 1f:起始透明度; 0f:动画结束后的透明度 */
2.组合动画
AnimatorSet:这个类提供了一个play()方法,调用后将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:
after(Animator anim):将现有动画插入到传入的动画之后执行after(long delay):将现有动画延迟指定毫秒后执行before(Animator anim): 将现有动画插入到传入的动画之前执行with(Animator anim):将现有动画和传入的动画同时执行
//沿x轴放大
ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 2f, 1f);
//沿y轴放大
ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(imageView, "scaleY", 1f, 2f, 1f);
//移动
ObjectAnimator translationXAnimator = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f, 0f);
//透明动画
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);
AnimatorSet set = new AnimatorSet();
//同时沿X,Y轴放大,且改变透明度,然后移动
set.play(scaleXAnimator).with(scaleYAnimator).with(animator).before(translationXAnimator);
//都设置3s,也可以为每个单独设置
set.setDuration(3000);
set.start();
3.监听事件
//添加监听事件
set.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) {
//动画重复执行的时候调用
}
});
//另一种设置监听的方式,里面的监听方法可以选择性重写
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
}
});
4.xml属性动画
这里提一下,属性动画当然也可以使用xml文件的方式实现,但是属性动画的属性值一般会牵扯到对象具体的属性,更多是通过代码动态获取,所以xml文件的实现会有些不方便。
<set android:ordering="sequentially">
<set>
<objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/>
<objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/>
</set>
<objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/>
</set>
使用方法:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
R.anim.property_animator);
set.setTarget(myObject);
set.start();
xml 文件中的标签也和属性动画的类相对应:
ValueAnimator --- <animator>
ObjectAnimator --- <objectAnimator>
AnimatorSet --- <set>
三.属性动画的核心原理
在上面实现属性动画的时候,我们反复的使用到了ObjectAnimator 这个类,这个类继承自ValueAnimator,使用这个类可以对任意对象的任意属性进行动画操作。而ValueAnimator是整个属性动画机制当中最核心的一个类;这点从下面的图片也可以看出。
1.核心类讲解
- ValueAnimator:Animator的子类,实现了动画的整个处理逻辑,也是熟悉动画最为核心的类
- ObjectAnimator:对象属性动画的操作类,继承自ValueAnimator,通过该类使用动画的形式操作对象的属性
- TimeInterpolator:时间插值器,它的作用是根据时间流逝的百分比来计算当前属性值改变的百分比,系统预置的有线性插值器、加速减速插值器、减速插值器等。
- TypeEvaluator:TypeEvaluator翻译为类型估值算法,它的作用是根据当前属性改变的百分比来计算改变后的属性值
- Property:属性对象、主要定义了属性的set和get方法
- PropertyValuesHolder:持有目标属性Property、setter和getter方法、以及关键帧集合的类。
- KeyframeSet:**存储一个动画的关键帧集

属性动画核心原理,此图来自于Android SDK API 文档。
属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等。
从上图我们可以了解到,通过duration、startPropertyValue和endPropertyValue 等值,我们就可以定义动画运行时长,初始值和结束值。然后通过start方法开始动画。 那么ValueAnimator 到底是怎样实现从初始值平滑过渡到结束值的呢?这个就是由TypeEvaluator 和TimeInterpolator 共同决定的。
具体来说,TypeEvaluator 决定了动画如何从初始值过渡到结束值。个人觉得可以看作一个方向。
TimeInterpolator 决定了动画从初始值过渡到结束值的节奏。个人觉得可以看作一个速度。
说的通俗一点,你每天早晨出门去公司上班,TypeEvaluator决定了你是坐公交、坐地铁还是骑车;而当你决定骑车后,TimeInterpolator决定了你一路上骑行的方式,你可以匀速的一路骑到公司,你也可以前半程骑得飞快,后半程骑得慢悠悠。
2.插值器Interpolator介绍
Interpolator的概念其实我们并不陌生,在补间动画中我们就使用到了。他就是用来控制动画快慢节奏的;而在属性动画中,TimeInterpolator 也是类似的作用;TimeInterpolator 继承自Interpolator。我们可以继承TimerInterpolator 以自己的方式控制动画变化的节奏,也可以使用Android 系统提供的Interpolator。
下面都是系统帮我们定义好的一些Interpolator,我们可以通过setInterpolator 设置不同的Interpolator。

这里我们使用的Interpolator就决定了 前面我们提到的fraction。变化的节奏决定了动画所执行的百分比。不得不说,这么ValueAnimator的设计的确是很巧妙。
这些就是属性动画的核心内容。现在使用属性动画的特性自定义动画应该不是难事了。其余便签的含义,结合之前的内容应该不难理解了
3.估值器Evaluator介绍
设置属性从初始值到结束值变化的具体数值
插值器(Interpolator)决定 值 的变化规律(匀速、加速blabla),即决定的是变化趋势;
而估值器属性动画特有的属性
四、传统动画 VS 属性动画
相较于传统动画,属性动画有很多优势。那是否意味着属性动画可以完全替代传统动画呢。其实不然,两种动画都有各自的优势,属性动画如此强大,也不是没有缺点。
- 补间动画中,虽然使用translate将图片移动了,但是点击原来的位置,依旧可以发生点击事件,而属性动画却不是。因此我们可以确定,属性动画才是真正的实现了view的移动,补间动画对view的移动更像是在不同地方绘制了一个影子,实际的对象还是处于原来的地方。
- 当我们把动画的repeatCount设置为无限循环时,如果在Activity退出时没有及时将动画停止,属性动画会导致Activity无法释放而导致内存泄漏,而补间动画却没有问题。因此,使用属性动画时切记在Activity执行 onStop 方法时顺便将动画停止。(对这个怀疑的同学可以自己通过在动画的Update 回调方法打印日志的方式进行验证)。
- xml 文件实现的补间动画,复用率极高。在Activity切换,窗口弹出时等情景中有着很好的效果。
- 使用帧动画时需要注意,不要使用过多特别大的图,容易导致内存不足。
边栏推荐
猜你喜欢

VIKINGS: 1 vulnhub walkthrough

如何在正则表达式里表达可能存在也可能不存在的内容?

Win10 解决AMD平台下SVM无法开启的问题

张量乘积—实验作业

财产清查概述、 全面清查的情况、局部清查的情况、财产清查的方法、财产清查结果的处理

链动2+1无限循环系统,2022年起盘成功率超高的模式

会计凭证概述、原始凭证、原始凭证的种类、原始凭证的基本内容、原始凭证的填制要求、原始凭证的审核
![WeChat applet development video loading: [Rendering layer network layer error] Failed to load media](/img/24/e12a1312aee28a43428b2ae0bfbe00.png)
WeChat applet development video loading: [Rendering layer network layer error] Failed to load media

Command Execution Vulnerability

会计账簿、会计账簿概述、会计账簿的启用与登记要求、会计账簿的格式和登记方法
随机推荐
【泰山众筹】模式为什么一直都这么火热?是有原因的
记账凭证的种类、记账凭证的基本内容、记账凭证的填制要求、记账凭证的审核
浅谈性能优化:APP的启动流程分析与优化
关于我的项目-微信公众号~
学IT,找工作——移除链表元素
hackmyvm: may walkthrough
财产清查概述、 全面清查的情况、局部清查的情况、财产清查的方法、财产清查结果的处理
Jetpack中各个组件简介
File upload vulnerability
阿里技术官手码12W字面试小册
真·杂项:资本论阅读笔记(随缘更新)
Offensive and defensive world - novice MISC area 1-12
什么是广告电商商业模式?这几个门派告诉你
解密:链动2+1的商业模式
xxe of CTF
Scrapy crawler encounters redirection 301/302 problem solution
(1) the print () function, escape character, binary and character encoding, variables, data type, the input () function, operator
【一句话攻略】彻底理解JS中的回调(Callback)函数
How to determine the direction based on two coordinate points on the map
c语言用栈实现计算中缀表达式