潍坊建设局网站,免费的crm系统,网站建设技术方面的论文,wordpress页面留言板8种机械键盘轴体对比本人程序员#xff0c;要买一个写代码的键盘#xff0c;请问红轴和茶轴怎么选#xff1f;前言相对于静态的页面#xff0c;动画往往能更直观地表达所需的信息#xff0c;在UI开发过程中起着相当大的作用。Android为我们提供了一系列实现动画效果的方法…8种机械键盘轴体对比本人程序员要买一个写代码的键盘请问红轴和茶轴怎么选前言相对于静态的页面动画往往能更直观地表达所需的信息在UI开发过程中起着相当大的作用。Android为我们提供了一系列实现动画效果的方法PropertyAnimaiton是最常见也是最实用的一种如同它的名字一样它的实现方式是通过改变对象的一系列属性值来改变对象的状态 例如动态地改变绘制的位置就可以实现绘制物体的移动效果动态地改变对象的显示状态可以实现闪烁效果。Animator概览Android提供的实现属性动画的工具是android.animation.Animator这个类它的使用需要配合animation包下的其他工具类这个类的功能是什么我们要如何使用它来实现属性动画呢我们可以将Animator理解为Android为我们提供的一个按我们的需要在一定时间段内连续地计算并返回值的工具这个值可以是通用的整型、浮点型也可以是我们自定义的类型。我们可以设置返回值的范围并可以控制值变化的快慢例如实现自由落体下落的物体时我们需要让高度值以一个越来越快的速度降低。这里的连续需要注意实际上是不可能产生真正意义上的连续值的但是如果在绘制过程中计算这个值的速度小于绘制一帧所需要的时间那么我们就可以在视觉上认为这个值是在连续改变的。这一点也是理解其作用的关键我们很难去写出一个可以随时获取连续值的工具而Animator正是一个满足我们这个需求的一个通用工具。通过将Animator与View的绘制过程结合就可以实现绝大多数的动画效果 但是Animator也不只局限在使用在绘制动画只要是有相似需求的地方都可以使用它来实现 同时由于属性动画只针对属性进行修改与被修改对象之前几乎没有耦合不需要对被修改对象作出改变可以设置方式也多种多样这些都是动画的另一种实现方法ViewAnimator所无法做到的所以我属性动画是现在实现动画效果的普遍做法。使用AnimatorAnimator子类下面就来看看如何使用Animator满足我们的需求。我们使用Animator可以分为两个步骤一是进行数值的计算二是将计算出的数值设置到对应的对象上。而Animator有着三个子类ValueAnimator ObjectAnimator AnimatorSet。ValueAnimator实现了上述过程的第一个步骤进行数值的计算。第二个步骤则需要我们重写它的回调在值发生改变时候手动地为对象更新属性值。ObjectAnimator则在其基础上进行了进一步的封装加入了一些方法使得它可以绑定一个对象在数值改变的同时对对象的属性进行更新。AnimatorSet可以对Animator进行组合让它们之间进行联动例如可以设置一个动画根据另一个动画的状态来决定是否开始、暂停或停止。可以看到ValueAnimator提供了一个Animator最核心的内容也是使用中最为灵活的一个。ObjectAnimator由于绑定了相应的对象在使用上会受一些限制。AnimatorSet专用于需要组合动画的场景。ValueAnimator在这篇博客中我们关注最为核心的ValueAnimator。关键属性ValueAnimator对象内部维护了一系列属性来保存所需的各种信息。Duration动画的持续时间通过setDuration()方法设置Repeat count and behavior重复计数与重复模式我们可以通过设置这两个属性来控制动画是否重复以及重复的次数通过setRepeatCount()与setRepeatMode()方法设置Frame refresh delay帧刷新延迟也就是计算两帧动画之间的间隔时间但这个时间只是Animator尽力去保持的值具体的间隔时间会由于系统负载与性能的不同而不同同时设置它的方法为一个静态方法ValueAnimator.setFrameDelay()会被设置到所有的Animator上这是因为这些Animator都在同一个时间循环中。这个属性也有可能会被忽略如果动画系统采用了内部的计时来源例如vsync来计算属性。同时这个方法需要在与start()方法相同的进程中调用Time interpolation时间插值器是我们实现不同动画效果的关键每一时刻所返回的数值由它决定后文会详细讲初始化与TypeEvaluatorValueAnimator对象的构造函数只由内部使用获取ValueAnimator对象的方法是调用它的工厂方法ValueAnimator.ofArgb()ValueAnimator.ofInt()ValueAnimator.ofFloat()ValueAnimator.ofObject()ValueAnimator.ofPropertyValuesHolder() //本篇未涉及下一篇进行讲解前三个可以看作是ValueAnimator为我们提供的初始化方式它们的参数都是对应类型的长度可变参数:(Type ...values)我们需要提供一个以上的参数ValueAnimator最终提供的值会在这些值之前变动。一般情况下这里提供的Argb(用于颜色值的变化)和整型、浮点值基本可以满足我们的需求但是某些时候我们需要结果是我们自定义的一些对象这个时候就需要用到TypeEvaluator接口了与这个接口对应的工厂方法是ValueAnimator.ofObject()12ValueAnimator (TypeEvaluator evaluator,Object... values)这里的可变参数类型变为了Object同时还需要我们提供一个TypeEvaluator用于“告诉”Animator如何返回这个Object值。TypeEvaluator接口并不复杂只有一个方法需要我们重写123T evaluate (float fraction,T startValue,T endValue)startValue与endValue非常好理解就是我们在获取Animator时指定的值的起始值和结束值。类型与返回类型一致当然都是我们自定义的类型。这里的fraction就是决定我们最终返回值的关键参数。我们可以把这个fraction理解为animator提供给我们的最终的数值改变的比例以小数表示小于0表示低于startValue大于0表示超出endValue0-1之间表示在startValue与endValue之间。我们要做的就是把这个值转换为在起始和结果范围之间的合适的对象值。例如对于基本的浮点类型默认的FloatEvaluator是这样的1234public Float evaluate(float fraction, Number startValue, Number endValue){float startFloat startValue.floatValue();return startFloat fraction * (endValue.floatValue() - startFloat);}可以看到就是相当于把fraction所表示的比例“投射”到了我们所需要的数据对象上这里是浮点类型。如果使用我们的自定义类型我们必须为自己的类型定义这样的操作。注意这里要求我们必须将fraction线性地反应到对应的类型上因为fraction反映的是最终的动画进度我们必须如实地按照这个进度改变我们的属性所以需要将result x0 t * (x1 - x0)这样的形式反映到我们自己的对象上。自定义了TypeEvaluator以后就可以作为参数使用在上面的obObject()工厂方法中了。插补细分器(Interpolators)下面介绍使用ValueAnimator控制值变化过程中最为重要的一个概念插补细分器(Interpolators)。它实际上是一个关于时间的函数 根据时刻的不同来返回不同的值进而来控制最后的输出的值。那么它是如何表示的呢系统为我们提供了一系列预置的Interpolators以较常用的LinearInterpolater为例顾名思义它是一个线性的插补细分器意味着输入与输出呈线性关系123public float getInterpolation(float input){return input;}输入输出的关键函数就是这个getInterpolation()了可以看到参数与返回值都是float类型input的值在0-1之间结合前面我们可以很容易理解这个input就是一个以0-1之间的小数表示的过去的时间值例如整个动画是1000ms当input为0.25的时候意味着现在的时间过去了250ms。而返回值就是经过我们的转换表示出的动画应该进行的时间的比例这里由于是线性的所以可以直接返回input这个值最后会到哪里呢自然就是给我们前面介绍的TypeEvaluator。下面一段源码展示了这个过程12345if (mInterpolator ! null) {fraction mInterpolator.getInterpolation(fraction);}return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(),mLastKeyframe.getValue());作为getInterpolation()参数的fraction代表着过去的时间比例这里调用我们设置的Interpolator来更新这个fraction现在这个fraction表示的就是动画已经进行的比例下一步就要根据它来获取对应的对象值(调用了我们之间谈到过的evaluate()方法这里的KeyFrame的概念会在之后的博客讲到)后面的两个参数就是传递给evaluate的起始与结束范围。最终我们就获得了一个按照我们设定的Interpolator返回的动画属性值。如果想要实现加速效果呢Android同样为我们提供了现成的AccelerateInterpolator1234567public float getInterpolation(float input){if (mFactor 1.0f) {return input * input;} else {return (float)Math.pow(input, mDoubleFactor);}}同样很简洁这里用到了mFactor与mDoubleFactor分别表示我们在构造函数里面设置的指数值1234public AccelerateInterpolator(float factor){mFactor factor;mDoubleFactor 2 * mFactor;}如果我们设置的为1会返回input的平方其他值则会返回input的mDoubleFactor次方使得动画属性可以以不同的函数曲线形式变化。如果我们要实现自己的Interpolator呢只需要实现TimeInterpolator接口这个接口只需要我们实现一个getInterpolation方法。我们可以根据input值返回不同的值来返回不同的值表示动画的进度。注意返回值的范围不一定要在0-1之间小于0或大小1的值可以表示超出预设范围的目标值。这篇博客到此结束在下一篇博客中将会以一个绘制自由落体的弹跳小球的示例来演示如何使用Animator与介绍它的回调函数。