Android中动画和图形

本文深入解析Android属性动画的原理及应用,包括Animator类及其派生类的使用、关键帧动画的实现方法、属性动画与视图动画的区别以及XML配置动画等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

综述

本文主要包括Android中动画、Drawable、Canvas、openGL以及硬件加速部分内容。

对于openGL可以使用framework层本身的API也可以使用本地的NDK进行编写,其中NDK编写的程序的运行效率更高。

Android中动画分为两类:属性动画和视图动画。

属性动画能对非View和View对象进行操作。而且其定义的动画运行的健壮性更好。

视图动画是View对象进行操作,只是改变透明的,旋转,图片拉伸收缩。不能对背景颜色等进行操作。视图动画的另一个缺点是,只能够在View画的位置进行修改,而不是View的真实位置。其优势是需要很少的代码并且建立的速度比较快。

属性动画:对单独的属性进行操作。

视图动画分为:

1)补间动画。对一张图片本身进行拉伸、透明度的修改和旋转等。

2)帧动画。对多张图片施加的动画。

一、属性动画。

这是Android动画中最为健壮的动画内容。你可以对在屏幕显示或者没有显示的任何对象的属性进行操作。你可以对其要进行的操作和动画持续时间进行设置。

      1)可以为动画指定持续时间,默认为300ms,并且指定动画的重复次数。

       2)可以将动画分成逻辑上的组,也可以将一个动画设定在一个具体动画结束之后再进行。

      3)为动画指定帧刷新延时。默认情况下是10ms但是最终是多长时间还是用系统当时运行的状态决定的。


1.属性动画。对于非View类型的只能使用property动画。

1)工作原理



Animator类是属性动画的基类,有三个派生类。

ValueAnimator   --> ObjectAnimator    AnimatorSet

其中ValueAnimator功能最为全面,objectAnimator是其派生类该类有了一些限制。AnimatorSet用于编排一段动画。

Evaluator用来让告诉属性动画如何计算值,其包含一个由Animator提供的时间数据,动画的开始时间和停止时间,并根据时间计算出这些属性的值。


Evaluators的类型:Int  Float   Argb(用于计算颜色的)    TypeEvaluators(用户可以继承该类实现自己的Evaluators)。

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);
    }
}



插值:定义了动画上的特定值是如何计算为时间的函数的。

Table 3. Interpolators

Class/Interface Description
AccelerateDecelerateInterpolator An interpolator whose rate of change starts and ends slowly but accelerates through the middle.
AccelerateInterpolator An interpolator whose rate of change starts out slowly and then accelerates.
AnticipateInterpolator An interpolator whose change starts backward then flings forward.
AnticipateOvershootInterpolator An interpolator whose change starts backward, flings forward and overshoots the target value, then finally goes back to the final value.
BounceInterpolator An interpolator whose change bounces at the end.
CycleInterpolator An interpolator whose animation repeats for a specified number of cycles.
DecelerateInterpolator An interpolator whose rate of change starts out quickly and and then decelerates.
LinearInterpolator An interpolator whose rate of change is constant.
OvershootInterpolator An interpolator whose change flings forward and overshoots the last value then comes back.
TimeInterpolator An interface that allows you to implement your own interpolator.
可以使用ValueAnimator的工厂方法ofInt ofFloat   ofObject来获得一个ValueAnimator的对象


ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.start();
当然上述代码没有对特定的对象进行处理。所以在实际应用中可以使用AnimatorListener对动画进行监听然后动态的修改动画。

ValueAnimator.AnimatorUpdateListener

所有的对View操作的setter方法(如setApha)的调用后都必须要调用invalidate方法然View重新绘制,这些方法中已经对invalidate方法进行了正确的调用。

ValueAnimatorAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}
AnimatorListenerAdapter对AnimatorUpdateListener进行了空实现,这样你就可以重写你需要的方法了。


ObjectAnimator中结合了时间引擎和属性值的计算的能力对特定对象上的属性就行操作。并且使用该类你就不用再使用监听器对动画进行处理了,因为其会对动画自动进行处理。

ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
anim.setDuration(1000);
anim.start();
其和ValueAnimator不同在于:必须在创建动画时就指定目标对象。

在该类中的目标对象必须有一个setter方法。如setFoo这是因为在自动修改的时候回去调用这个方法。如果没有改方法,那么你需要使用一个包裹类将该对象包裹起来,然后在提供setter方法。对于foo对象的所有的属性你必须为其提供相应的getter方法。因为程序需要调用getter方法来获取其当前设定的值。



使用AnimatorSet编排多个动画。

  1. Plays bounceAnim.
  2. Plays squashAnim1squashAnim2stretchAnim1, 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();

给布局添加动画改编ViewGroup

可以控制其中的View的出现或者消失。

  • APPEARING - A flag indicating the animation that runs on items that are appearing in the container.
  • CHANGE_APPEARING - A flag indicating the animation that runs on items that are changing due to a new item appearing in the container.
  • DISAPPEARING - A flag indicating the animation that runs on items that are disappearing from the container.
  • CHANGE_DISAPPEARING - A flag indicating the animation that runs on items that are changing due to an item disappearing from the container.
使用LayoutTransition类。

但是需要在布局文件中对其进行设置

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />

关键帧keyframe

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);
To instantiate a  Keyframe  object, you must use one of the factory methods,  ofInt() ofFloat() , or  ofObject()  to obtain the appropriate type of  Keyframe . You then call the  ofKeyframe()  factory method to obtain a PropertyValuesHolder  object. Once you have the object, you can obtain an animator by passing in the PropertyValuesHolder  object and the object to animate. The following code snippet demonstrates how to do this:


动画视图的部分说明:

  • translationX and translationY: These properties control where the View is located as a delta from its left and top coordinates which are set by its layout container.
  • rotationrotationX, and rotationY: These properties control the rotation in 2D (rotation property) and 3D around the pivot point.
  • scaleX and scaleY: These properties control the 2D scaling of a View around its pivot point.
  • pivotX and pivotY: These properties control the location of the pivot point, around which the rotation and scaling transforms occur. By default, the pivot point is located at the center of the object.
  • x and y: These are simple utility properties to describe the final location of the View in its container, as a sum of the left and top values and translationX and translationY values.
  • alpha: Represents the alpha transparency on the View. This value is 1 (opaque) by default, with a value of 0 representing full transparency (not visible).

To animate a property of a View object, such as its color or rotation value, all you need to do is create a property animator and specify the View property that you want to animate. For example:

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);
视图属性动画的使用:

ViewPropertyAnimator提供一一种并行处理一个View的多个属性的解决方案。并且其运行更加高效,代码可读性高

Multiple ObjectAnimator objects

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

One 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);

属性动画提供了两种方式然用户来定制一个动画,上面都是使用代码的方式,下面讲解使用XML文件的方式。

为了区分使用了新的属性动画API的动画和之前老旧的视图动画框架的API,Android从3.1开始要求将新的动画XML文件声明在res/animator/目录下,并且ADT只识别这个目录。而不是之前的res/anim目录。

The following property animation classes have XML declaration support with the following XML tags:

<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();
上述为调用实例。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值