博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Animations】属性动画概述(2)
阅读量:7027 次
发布时间:2019-06-28

本文共 14165 字,大约阅读时间需要 47 分钟。

概要


属性动画系统是一个强大的框架,可以让你几乎任何动画。您可以定义动画来随时间改变任何对象属性,而不管它是否绘制到屏幕上。属性动画会在指定的时间长度内更改属性的(对象中的字段)值。要为某些东西设置动画,可以指定要设置动画效果的对象属性,例如对象在屏幕上的位置,要为其设置动画效果的时间长度,以及要在两者之间进行动画处理的值。

属性动画系统允许您定义动画的以下特征:

  • 持续时间:您可以指定动画的持续时间。默认长度是300毫秒。
  • 时间插值:您可以指定如何根据动画当前流逝的时间计算属性的值。
  • 重复次数和行为:您可以指定是否在动画结束时重复动画,以及重复动画的次数。您还可以指定是否要让动画反向播放。将其设置为反向播放动画,然后反复向后播放,直到达到重复次数。
  • 动画师集:您可以将动画分组为逻辑集,这些逻辑集可以一起或按顺序播放,也可以在指定的延迟之后播放。
  • 帧刷新延迟:您可以指定刷新动画帧的频率。默认设置为每10毫秒刷新一次,但应用程序刷新帧的速度最终取决于系统整体的繁忙程度以及系统为底层计时器提供服务的速度。

要查看属性动画的完整示例,请参阅 示例中的 ChangeColor类。

属性动画如何运作


首先,让我们通过一个简单的例子来看看动画是如何工作的。图1描绘了一个假设对象,该对象使用其x属性进行动画处理,该属性表示其在屏幕上的水平位置。动画的持续时间设置为40毫秒,行进距离为40像素。每10毫秒(默认帧刷新率),对象水平移动10个像素。在40ms结束时,动画停止,并且对象在水平位置40结束。这是具有线性插值的动画的示例,这意味着对象以恒定的速度移动。

【Animations】属性动画概述(2)
图1.线性动画的例子

您还可以指定动画以进行非线性插值。图2展示了一个假设对象,该对象在动画开始时加速,并在动画结束时减速。该对象仍然在40毫秒内移动40个像素,但是非线性。开始时,这个动画加速到中途点,然后从中途点减速直到动画结束。如图2所示,动画开始和结束时的行进距离比中间的小。

【Animations】属性动画概述(2)
图2.非线性动画的例子
让我们详细看看属性动画系统的重要组件如何计算上面所示的动画。图3描述了主要类如何相互协作。
【Animations】属性动画概述(2)
图3.如何计算动画

该ValueAnimator对象会跟踪动画的时间,如动画运行的时间长度以及动画的属性的当前值。

定义动画插值的ValueAnimator封装a TimeInterpolator和TypeEvaluator定义如何计算正在动画的属性的值的a。例如,在图2中,所TimeInterpolator使用的将是 AccelerateDecelerateInterpolator和TypeEvaluator将会IntEvaluator。

要开始动画,请创建一个动画ValueAnimator并为其指定要设置动画的属性的开始和结束值以及动画的持续时间。当你调用start()动画开始。在整个动画过程中 ,根据动画持续时间和已经过多少时间,ValueAnimator计算0和1之间的经过小数。经过的分数表示动画完成的时间百分比,0表示0%,1表示100%。例如,在图1中,t = 10 ms处的流逝分数将为.25,因为总持续时间为t = 40 ms。

当ValueAnimator完成计算经过的分数时,它调用TimeInterpolator当前设置的分数来计算 内插分数。内插分数将流逝分数映射到考虑了设置的时间内插的新分数。例如,在图2中,由于动画缓慢加速,因此在t = 10 ms时,插值分数约为0.15,小于流逝分数.25。在图1中,内插分数总是与流逝分数相同。

计算插值分数时,根据内插分数,起始值和动画结束值ValueAnimator调用适当TypeEvaluator的值,以计算您正在动画的属性的值。例如,在图2中,插值分数在t = 10 ms时为.15,因此当时属性的值为.15×(40 - 0)或6。

属性动画与视图动画的不同之处


视图动画系统提供了仅对View 对象进行动画处理的功能,因此如果要为非View对象设置动画效果,则必须执行自己的代码才能实现动画效果。视图动画系统也受到限制,因为它仅暴露View对象的几个方面以进行动画制作,例如视图的缩放和旋转,而不是背景色。

视图动画系统的另一个缺点是只能在视图被绘制的地方进行修改,而不是实际的视图本身。例如,如果您为按钮在屏幕上移动设置动画,该按钮绘制正确,但您可以单击该按钮的实际位置不会更改,因此您必须实现自己的逻辑来处理此操作。

通过属性动画系统,这些约束被完全删除,并且可以为任何对象(视图和非视图)的任何属性设置动画,并且对象本身实际上被修改。属性动画系统在执行动画时也更加健壮。在较高的层次上,您可以将动画设计人员分配给您想要制作动画的属性,例如颜色,位置或大小,并且可以定义动画的各个方面,例如插值和多个动画师的同步。

然而,视图动画系统需要更少的时间进行设置,并且需要的代码更少。如果视图动画完成了您需要执行的所有操作,或者您的现有代码已按照您的要求运行,则无需使用属性动画系统。如果出现用例,那么在不同情况下使用这两种动画系统也是有意义的。

API概述


你可以在其中找到大部分属性动画系统的API android.animation。由于视图动画系统已经定义了许多内插器android.view.animation,因此您也可以在属性动画系统中使用这些内插器。下表介绍了属性动画系统的主要组件。

该Animator课程提供了创建动画的基本结构。您通常不直接使用此类,因为它只提供最小的功能,必须扩展才能完全支持动画值。以下子类扩展Animator:

【Animations】属性动画概述(2)
表2.Evaluators
【Animations】属性动画概述(2)
时间插值器定义动画中的特定值如何作为时间的函数进行计算。例如,您可以指定动画在整个动画中线性发生,这意味着动画会平均移动整个时间,也可以指定动画以使用非线性时间,例如,开始时加速并在结束时减速动画。表3描述了包含在其中的插入器android.view.animation。如果所提供的插补器都不符合您的需求,请实现TimeInterpolator接口并创建您自己的插件。有关如何编写自定义插补器的更多信息,请参见使用插补器。
表3.插值器
【Animations】属性动画概述(2)

使用ValueAnimator进行动画制作


的ValueAnimator类,可以通过指定一组的动画某种类型为动画的持续时间的值int,float或颜色值进行动画通过。您获得ValueAnimator通过调用其工厂方法之一:ofInt(),ofFloat()或ofObject()。例如:

ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);animation.setDuration(1000);animation.start();

在此代码中,ValueAnimator当start()方法运行时,开始计算动画的值,介于0和100之间,持续时间为1000毫秒。

您还可以通过执行以下操作来指定一个自定义类型来设置动画效果:

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);animation.setDuration(1000);animation.start();

在此代码中,当方法运行时,ValueAnimator开始计算动画的值,之间startPropertyValue以及endPropertyValue使用所提供的逻辑MyTypeEvaluator持续1000毫秒start()。

您可以通过将对象添加AnimatorUpdateListener 到动画中来使用动画的值 ValueAnimator,如下面的代码所示:

animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator updatedAnimation) {        // You can use the animated value in a property that uses the        // same type as the animation. In this case, you can use the        // float value in the translationX property.        float animatedValue = (float)updatedAnimation.getAnimatedValue();        textView.setTranslationX(animatedValue);    }});

在该onAnimationUpdate() 方法中,您可以访问更新后的动画值并将其用于其中一个视图的属性中。有关侦听器的更多信息,请参阅关于动画侦听器的部分 。

使用ObjectAnimator进行动画制作


这ObjectAnimator是ValueAnimator(上一节讨论的)的一个子类,它将时序引擎和值计算ValueAnimator与对目标对象的命名属性进行动画处理的能力相结合。这使得任何对象的动画更容易,因为你不再需要实现ValueAnimator.AnimatorUpdateListener,因为动画属性会自动更新。

实例化ObjectAnimator类似于a ValueAnimator,但您还要指定对象和该对象属性的名称(作为字符串)以及值之间进行动画处理:

ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);animation.setDuration(1000);animation.start();

要ObjectAnimator正确获取更新属性,您必须执行以下操作:

  • 您正在设置动画的对象属性必须具有一个setter函数(骆驼大小写) set<PropertyName>()。由于ObjectAnimator 在动画期间自动更新属性,因此必须能够使用此setter方法访问属性。例如,如果属性名称是foo,您需要有一个setFoo()方法。如果这个setter方法不存在,你有三个选择:
    • 如果您有权这样做,请将setter方法添加到该类中。
    • 使用您有权修改的包装类,并让该包装接收有效的setter方法的值并将其转发给原始对象。
    • ValueAnimator改为使用。
  • 如果您values...在其中一个ObjectAnimator工厂方法中只为参数指定了一个值,则假定它是动画的结束值。因此,您正在动画的对象属性必须具有用于获取动画起始值的getter函数。getter函数的格式必须为get<PropertyName>()。例如,如果属性名称是 foo,您需要有一个getFoo()方法。

  • 您要动画的属性的getter(如果需要)和setter方法必须与您指定的开始和结束值的操作类型相同ObjectAnimator。例如,您必须拥有 targetObject.setPropName(float)并且targetObject.getPropName(float) 构建以下内容ObjectAnimator:
    ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);animation.setDuration(1000);animation.start();
  • 根据您正在动画的属性或对象,您可能需要invalidate()在视图上调用该方法以强制屏幕使用更新后的动画值重绘本身。你在onAnimationUpdate() 回调中这样做 。例如,对Drawable对象的颜色属性进行动画处理只会导致该对象重绘时自动更新屏幕。所有的景观,物业制定者如 setAlpha()和setTranslationX() 正确无效视图,所以你不需要调用这些方法与新的值时无效视图。有关侦听器的更多信息,请参阅关于的部分 。

使用AnimatorSet编排多个动画


在许多情况下,您想播放取决于另一个动画何时开始或结束的动画。Android系统允许您将动画组合到一起AnimatorSet,以便您可以指定是同时,按顺序开始动画还是在指定的延迟之后开始动画。您也可以AnimatorSet在彼此中嵌套对象。

以下代码片段Animator 按以下方式播放以下对象:

  1. Plays bounceAnim.
  2. Plays squashAnim1, squashAnim2, stretchAnim1, and stretchAnim2 at the same time.
  3. Plays bounceBackAnim.
  4. Plays fadeAnim.
AnimatorSet bouncer = new AnimatorSet();bouncer.play(bounceAnim).before(squashAnim1);bouncer.play(squashAnim1).with(squashAnim2);bouncer.play(squashAnim1).with(stretchAnim1);bouncer.play(squashAnim1).with(stretchAnim2);bouncer.play(bounceBackAnim).after(stretchAnim2);ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);fadeAnim.setDuration(250);AnimatorSet animatorSet = new AnimatorSet();animatorSet.play(bouncer).before(fadeAnim);animatorSet.start();

动画侦听器


您可以在动画持续时间期间与下面介绍的听众一起收听重要事件。

  • Animator.AnimatorListener

    • onAnimationStart() - 动画开始时调用。
    • onAnimationEnd() - 动画结束时调用。
    • onAnimationRepeat() - 当动画重复时调用。
    • onAnimationCancel() - 当动画被取消时调用。onAnimationEnd()无论如何结束,取消的动画也会调用。
  • ValueAnimator.AnimatorUpdateListener

    • onAnimationUpdate() - 调用动画的每一帧。收听此事件以使用ValueAnimator动画期间生成的计算值。要使用该值,请查询ValueAnimator传入事件的对象以通过getAnimatedValue()方法获取当前动画值。如果您使用,则需要实现此侦听器ValueAnimator。

    • 根据您要动画的属性或对象,您可能需要调用 invalidate()View来强制屏幕区域使用新的动画值重新绘制自己。例如,对Drawable对象的颜色属性进行动画处理只会导致该对象重绘时自动更新屏幕。所有的景观,物业制定者如setAlpha()和 setTranslationX()正确无效视图,所以你不需要调用这些方法与新的值时无效视图。

如果您不想实现 接口的所有方法,则可以扩展AnimatorListenerAdapter该类而不是实现Animator.AnimatorListener该Animator.AnimatorListener接口。本AnimatorListenerAdapter类提供的,你可以选择覆盖的方法的空实现。

例如,下面的代码片段AnimatorListenerAdapter 为onAnimationEnd() 回调创建一个:

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);fadeAnim.setDuration(250);fadeAnim.addListener(new AnimatorListenerAdapter() {public void onAnimationEnd(Animator animation) {    balls.remove(((ObjectAnimator)animation).getTarget());}

将布局更改动画到ViewGroup对象


属性动画系统提供了对ViewGroup对象进行动画变化的功能,并提供了一种简单的方法来为View对象本身制作动画。

您可以使用LayoutTransition该类在ViewGroup内动画布局更改 。ViewGroup中的视图可以在将ViewGroup添加到ViewGroup中或从ViewGroup中删除它们时,或者setVisibility()使用,,或 调用View的方法时 VISIBLE,经历出现和消失的动画 。当您添加或删除视图时,ViewGroup中的其余视图也可以动画到其新位置。您可以通过调用 并传入具有以下常量之一的对象来在对象中定义以下动画:INVISIBLEGONELayoutTransitionsetAnimator()AnimatorLayoutTransition

  • APPEARING - 一个标志,指示在容器中出现的项目上运行的动画。
  • CHANGE_APPEARING - 一个标志,表示在由于容器中出现新项目而正在更改的项目上运行的动画。
  • DISAPPEARING - 一个标志,指示在从容器中消失的物品上运行的动画。
  • CHANGE_DISAPPEARING - 一个标志,表示在由于某个项目从容器中消失而更改的项目上运行的动画。

您可以为这四种类型的事件定义自己的自定义动画,以自定义布局转换的外观,或者仅告诉动画系统使用默认动画。

API演示中的 LayoutAnimations示例向您展示了如何为布局转换定义动画,然后在您想要制作动画的View对象上设置动画。

该 LayoutAnimationsByDefault及其相应layout_animations_by_default.xml 布局资源文件告诉你如何启用默认的布局转换为XML ViewGroups。唯一需要做的就是将该android:animateLayoutchanges 属性设置true为ViewGroup。例如:

将此属性设置为true会自动生成从ViewGroup添加或删除的视图以及ViewGroup中剩余的视图。

使用StateListAnimator动画化视图状态更改


本StateListAnimator类允许您定义动画运行时的景色变化的状态。该对象表现为对象的包装, Animator每当指定的视图状态(例如“按下”或“聚焦”)发生更改时调用该动画。

在StateListAnimator可与一个根XML资源被定义 <selector>元素和子<item>每个指定由所限定的不同视图状态元素StateListAnimator类。每个都 <item>包含属性动画集的定义。

例如,以下文件会创建一个状态列表动画器,用于在按下时更改视图的x和y比例:

RES / XML / animate_scale.xml

要将状态列表动画添加到视图,请按如下所示添加属性: android:stateListAnimator

现在animate_scale.xml当这个按钮的状态改变时,使用定义的动画。

或者,也可以将状态列表动画器分配给代码中的视图,使用该AnimatorInflater.loadStateListAnimator()方法,并使用该 方法将动画器分配给视图View.setStateListAnimator()。

或者,也可以不使用视图的动画属性,而是使用状态更改之间播放可绘制动画AnimatedStateListDrawable。Android 5.0中的一些系统小部件默认使用这些动画。以下示例显示如何将AnimatedStateListDrawable一个XML资源定义为:

...
...

使用TypeEvaluator


如果您想为Android系统未知的类型创建动画,可以通过实现该TypeEvaluator界面来创建自己的评估器。由Android系统中已知的类型是int,float,或颜色,其由支持IntEvaluator,FloatEvaluator和ArgbEvaluator类型评估。

只有一种方法可以在TypeEvaluator 界面中实现,即evaluate()方法。这允许您正在使用的动画设计人员在动画当前点为您的动画属性返回适当的值。该FloatEvaluator课程演示了如何做到这一点:

public class FloatEvaluator implements TypeEvaluator {    public Object evaluate(float fraction, Object startValue, Object endValue) {        float startFloat = ((Number) startValue).floatValue();        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);    }}

注意:当ValueAnimator(或ObjectAnimator)运行时,它会计算动画的当前流逝部分(介于0和1之间的值),然后根据您正在使用的插值器计算插值版本。内插分数是您TypeEvaluator通过fraction参数接收到的分数,因此您在计算动画值时不必考虑内插器。

使用插值器


内插器定义动画中特定值如何作为时间的函数进行计算。例如,您可以指定动画在整个动画中线性发生,这意味着动画会平均移动整个时间,或者您可以指定动画以使用非线性时间,例如在开始或结束时使用加速或减速动画。

动画系统中的插值器会接收来自动画师的一小部分,表示动画已用时间。插值器修改此分数以符合它旨在提供的动画类型。Android系统提供了一组常用的插值器android.view.animation package。如果这些都不符合您的需求,您可以实现TimeInterpolator界面并创建自己的界面。

作为一个例子,默认插补器AccelerateDecelerateInterpolator和LinearInterpolator计算插值分数如何在下面进行比较。在LinearInterpolator对过去部分没有任何影响。在AccelerateDecelerateInterpolator加速进入动画和减速出来。以下方法定义了这些内插器的逻辑:

AccelerateDecelerateInterpolator

public float getInterpolation(float input) {    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;}

LinearInterpolator

public float getInterpolation(float input) {    return input;}

下表代表这些插补器对持续1000毫秒的动画计算的近似值:

【Animations】属性动画概述(2)
如表格所示,LinearInterpolator以相同的速度改变数值,.2每200ms通过一次。该AccelerateDecelerateInterpolator值LinearInterpolator在200ms和600ms之间变化更快,在600ms和1000ms之间变化更慢。

指定关键帧


一个Keyframe对象由一个时间/值对组成,可让您在动画的特定时间定义特定状态。每个关键帧还可以具有自己的插补器,以控制前一关键帧时间与该关键帧时间之间的间隔中的动画行为。

实例化一个Keyframe对象,你必须使用的工厂方法之一,ofInt(),ofFloat(),或ofObject()以获取相应的类型Keyframe。然后您调用ofKeyframe()工厂方法来获取PropertyValuesHolder对象。一旦你有了这个对象,你就可以通过传入PropertyValuesHolder对象和对象来获得动画。以下代码片段演示了如何执行此操作:

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);Keyframe kf2 = Keyframe.ofFloat(1f, 0f);PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)rotationAnim.setDuration(5000ms);

动画视图


属性动画系统允许View对象的简化动画,并且与视图动画系统相比具有一些优点。视图动画系统通过改变它们被绘制的方式来转换视图对象。这是在每个视图的容器中处理的,因为视图本身没有可操作的属性。这导致视图被动画,但在视图对象本身中没有改变。这导致行为,例如对象仍然存在于其原始位置,即使它是在屏幕上的不同位置绘制的。在Android 3.0中,添加了新的属性和相应的getter和setter方法来消除这个缺点。

属性动画系统可以通过更改视图对象中的实际属性来在屏幕上动画视图。另外,视图也会自动调用该invalidate() 方法刷新屏幕,只要其属性发生更改。View帮助属性动画的类中的新属性是:

  • translationX和translationY:这些属性控制视图所在的位置,作为其布局容器设置的左侧和顶部坐标的增量。
  • rotation,,rotationX和rotationY:这些属性控制rotation围绕枢轴点的2D(属性)和3D旋转。
  • scaleX和scaleY:这些属性控制视图围绕其中心点的2D缩放比例。
  • pivotX以及pivotY:这些属性控制旋转点的位置,旋转和缩放变换将围绕该点进行。默认情况下,枢轴点位于对象的中心。
  • x和y:这些都是简单的实用属性,用于描述视图在其容器中的最终位置,作为左值和顶值以及translationX和translationY值的总和。
  • alpha:表示视图上的Alpha透明度。该值默认为1(不透明),值为0表示完全透明(不可见)。

要为View对象的属性(例如其颜色或旋转值)设置动画效果,您只需创建属性动画器并指定要设置动画效果的View属性即可。例如:

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

有关创建动画的更多信息,请参阅关于使用ValueAnimator和ObjectAnimator进行动画制作的章节 。

使用ViewPropertyAnimator进行动画制作

在ViewPropertyAnimator提供了一个简单的方法来制作动画的几个属性View并联,使用单个底层Animator 对象。它的行为非常类似于an ObjectAnimator,因为它会修改视图属性的实际值,但在同时为多个属性制作动画时效率会更高。此外,使用该代码ViewPropertyAnimator更简洁,更易于阅读。以下代码片段显示了在使用多个ObjectAnimator对象,单个对象 ObjectAnimator以及ViewPropertyAnimator何时同时为视图设置动画x和y属性方面的差异 。

多个ObjectAnimator对象

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);AnimatorSet animSetXY = new AnimatorSet();animSetXY.playTogether(animX, animY);animSetXY.start();

一个ObjectAnimator

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();

ViewPropertyAnimator

myView.animate().x(50f).y(100f);

有关更多详细信息ViewPropertyAnimator,请参阅相应的Android开发者 博客文章。

用XML声明动画


属性动画系统允许您用XML声明属性动画,而不是以编程方式进行。通过用XML定义动画,您可以轻松地在多个活动中重复使用动画,并更轻松地编辑动画序列。

为了将使用新属性动画API的动画文件与使用旧视图动画框架的动画文件区分开来,从Android 3.1开始,应该将用于属性动画的XML文件保存在res/animator/目录中。

以下属性动画类使用以下XML标记支持XML声明:

  • ValueAnimator - <animator>
  • ObjectAnimator - <objectAnimator>
  • AnimatorSet - <set>

要查找可以在XML声明中使用的属性,请参阅动画资源。以下示例按顺序播放两组对象动画,第一个嵌套组同时播放两个对象动画:

为了运行此动画,您必须将代码中的XML资源充满到AnimatorSet对象中,然后在开始动画设置之前为所有动画设置目标对象。为方便起见,调用setTarget()为所有孩子设置了一个目标对象AnimatorSet。以下代码显示了如何执行此操作:

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,    R.anim.property_animator);set.setTarget(myObject);set.start();

您还可以ValueAnimator用XML 声明一个,如下例所示:

要ValueAnimator在代码中使用先前的代码,您必须膨胀对象,添加 AnimatorUpdateListener,获取更新后的动画值,并将其用于其中一个视图的属性中,如以下代码所示:

ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this,        R.animator.animator);xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator updatedAnimation) {        float animatedValue = (float)updatedAnimation.getAnimatedValue();        textView.setTranslationX(animatedValue);    }});xmlAnimator.start();

有关定义属性动画的XML语法的信息,请参阅动画资源。

对UI性能的潜在影响


更新UI的动画师会为动画运行的每个帧导致额外的渲染工作。因此,使用资源密集型动画可能会对应用程序的性能产生负面影响。

将渲染UI的动画添加到渲染管道的动画阶段。您可以通过启用Profile GPU渲染和监控动画阶段来了解您的动画是否会影响应用的性能。有关更多信息,请参阅配置文件GPU渲染演练。

Lastest Update:2018.04.24

联系我

QQ:94297366

微信打赏:

公众号推荐:

【Animations】属性动画概述(2)

转载于:https://blog.51cto.com/4789781/2120969

你可能感兴趣的文章
网易云音乐下载|网易云音乐电脑版下载
查看>>
linux 主机名常忽略的小问题
查看>>
Lock wait timeout exceeded; try restarting tran...
查看>>
存储过程优势
查看>>
2012年4月MVP申请截止时间:2012年1月12日
查看>>
mydns的安装
查看>>
tar增量备份
查看>>
xen 故障汇总
查看>>
SecureCRT的使用--增加队列
查看>>
搭建gitlab
查看>>
linux常用命令-cd/type/printenv/hash
查看>>
python第二章 变量
查看>>
数据中心虚拟化需要大二层网络
查看>>
在Exchange server 2007中管理pop3和IMAP4协议访问
查看>>
后台在线编辑模板禁止提交含有{php 的标签解决办法
查看>>
《iPhone与iPad开发实战—iOS经典应用剖析》连载二
查看>>
软raid的详细配置讲解 raid 1
查看>>
js中通用的Object属性和方法
查看>>
如何在App中实现IM功能之六快速实现群聊的高级功能——箭扣科技Arrownock
查看>>
dig一些常用例子
查看>>