属性动画

来源:互联网 发布:什么是矩阵音响 编辑:程序博客网 时间:2024/04/29 22:42

属性(Property)动画

属性(Property)动画:安卓提供的众多动画中的一种,从某种角度来看,属性动画实际上是增强版的补间(Tween)动画。

属性动画主要由两方面组成:

1.计算各帧的相关属性值。
2.给指定的对象设置相关的属性值。

区别:

1.补间(Tween)动画只能够操控各种组件的透明度(alpha),位置(translate),

旋转(rotate)和放缩(scale)四种属性进行相应的变换,但是属性(Property)动画可以对任何的属性值做出改变。

2.补间(Tween)动画只能对UI组件作用,但是属性(Property)动画没有限制,可以对任何对象进行操作。

属性动画API:

1.ValueAnimator:属性动画主要的时间引擎,它负责计算各个帧的属性值,也就是属性动画第一组成部分。由于ValueAnimator只会负责第一部分,第二部分给组件赋属性值就需要手动完成。

2.ObjectAnimator:ValueAnimator的子类,在使用的时候可以直接指定组件对象,使用起来更加的方便了。但是在某些场景下,ObjectAnimator存在一些限制,可能需要考虑使用ValueAnimator。

3.AnimatorSet:Animator的子类,可以用于组合多个Animator对象,还可以指定是按次序播放还是同时播放。

在ValueAnimator中还用到了一个计算工具类Evaluator(计算器),控制者属性动画如何计算属性值。Android提供了集中Evaluator:

1.IntEvaluator:用于计算int类型的属性值计算器。

2.FloatEvaluator:用于计算float类型的属性值计算器。

3.ArgbEvaluator:用于计算十六进制的rgb颜色值。

4.TypeEvaluator:计算器的接口,供自定义计算器实现。

使用ValueAnimator创建动画大致如下四个步骤:

1.调用ValueAnimator的ofInt(), ofFloat(), ofObject()静态方法创建ValueAnimator实例,很明显这几个不同的方法创建的不同实例中,所用到的计算器也是不同的。2.调用ValueAnimator的setDuration()等方法给属性动画设置相应的参数,如动画的持续时间,重复次数等。3.调用start()方法启动相应的动画。4.为ValueAnimator注册AnimatorUpdateListener监听器,在监听器中可以实时获取到ValueAnimator计算出来的属性值,只需要在监听器中赋值给对应对象就行了。例如:
    ValueAnimator animation = ValueAnimator.ofFloat(1f, 0f);    animation.setDuration(3000);    animation.setRepeatCount(1);    animation.start();    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                /**                 * 使用的时候可以通过getAnimatedValue()来获取当前计算出来的帧的属性值,并赋值给制定对象。                 */            }        });
如果是希望使用自己利用TypeEvaluator定义出来的属性值计算器,则将第一步改为:
    ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(),1f, 0f);

2.使用ObjectAnimator创建动画和ValueAnimator差不多,只不过ObjectAnimator已经实现了将计算结果赋值给对象,我们在使用的时候提供控件对象,

不需要注册AnimatorUpdateListener监听器(没有上述的第四个步骤)。

例如:
    ObjectAnimator animation = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1f);    animation.setDuration(1000);    animation.setRepeatCount(1);    animation.start();
注意:    1.在使用ObjectAnimator的对象上一定要有改变的属性值,例如上述的例子中imageView一定要有alpha这个属性值。    2.如果在第一句话是
    ObjectAnimator animation = ObjectAnimator.ofFloat(imageView, "alpha", 1f);
    少提供了一个参数,则提供的值会被认为是属性计算的结束值,对alpha这个属性一定要提供getter方法,返回的值将作为属性计算的初始值,也就是从该组件的当前状态开始执行动画。    3.如果动画的对象是View,为了能显示动画的效果,需要不断的通知组件重新绘制,调用View.invalidate()方法,    但是View定义的setter方法,如setAloha()等方法都会自动的调用invalidate()方法,不需要我们再额外的调用了。
/** * 图形类 * 在实例中是一个圆 */public class ShapeHolder {    private float x = 0, y = 0;    private ShapeDrawable shape;    private int color;    private RadialGradient gradient;    private float alpha = 1f;    private Paint paint;    public ShapeHolder(ShapeDrawable s) {        shape = s;    }    public float getWidth() {        return shape.getShape().getWidth();    }    public void setWidth(float width) {        Shape s = shape.getShape();        s.resize(width,s.getWidth());    }    public float getHeight() {        return shape.getShape().getHeight();    }    public void setHeight(float height) {        Shape s = shape.getShape();        s.resize(height,s.getHeight());    }    public float getX() {        return x;    }    public void setX(float x) {        this.x = x;    }    public float getY() {        return y;    }    public void setY(float y) {        this.y = y;    }    public int getColor() {        return color;    }    public void setColor(int color) {        this.color = color;    }    public ShapeDrawable getShape() {        return shape;    }    public void setShape(ShapeDrawable shape) {        this.shape = shape;    }    public RadialGradient getGradient() {        return gradient;    }    public void setGradient(RadialGradient gradient) {        this.gradient = gradient;    }    public float getAlpha() {        return alpha;    }    public void setAlpha(float alpha) {        this.alpha = alpha;    }    public Paint getPaint() {        return paint;    }    public void setPaint(Paint paint) {        this.paint = paint;    }}public class MainActivity extends Activity {    static final float BALL_SIZE = 50F;    /**     * 用来控制动画执行的时间     */    static final float FULL_TIME = 1000;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        LinearLayout container = (LinearLayout) findViewById(R.id.root);        /**         * 将自定义控件加入到布局中         */        container.addView(new MyAniamtionView(this));    }    /**     * 自定义View     * 实现了AnimatorUpdateListener监听类     */    public class MyAniamtionView extends View implements ValueAnimator.AnimatorUpdateListener {        /**         * 存储多个小球的容器         */        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();        public MyAniamtionView(Context context) {            super(context);            setBackgroundColor(Color.WHITE);        }        @Override        public boolean onTouchEvent(MotionEvent event) {            //在手指触摸的地方添加一个小球            ShapeHolder newBall = addBall(event.getX(), event.getY());            float startY = newBall.getY();            float endY = getHeight() - BALL_SIZE;            float h = (float) getHeight();            float eventY = event.getY();            int duration = (int) (FULL_TIME * ((h - eventY) / h));            //用ValueAnimator定义落下的动画            ValueAnimator fallAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY);            fallAnim.setDuration(duration);            fallAnim.setInterpolator(new AccelerateInterpolator());            //用ObjectAnimator定义落下的动画            ObjectAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", endY, startY);            bounceBackAnim.setDuration(duration);            bounceBackAnim.setInterpolator(new DecelerateInterpolator());            fallAnim.addUpdateListener(this);            //定义小球透明度的动画            ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);            fadeAnim.setDuration(250);            fadeAnim.addListener(new AnimatorListenerAdapter() {                @Override                public void onAnimationEnd(Animator animation) {                    balls.remove(((ObjectAnimator)animation).getTarget());                }            });            fadeAnim.addUpdateListener(this);            //定义一个AnimatorSet来将定义的三个动画排序            AnimatorSet animatorSet = new AnimatorSet();animatorSet.play(fallAnim).before(bounceBackAnim);           animatorSet.play(bounceBackAnim).before(fadeAnim);            animatorSet.start();            return true;        }        /**         * 向小球集合ArrayList中加入小球         * 设置各种属性坐标等         *         * @param x         * @param y         * @return         */        private ShapeHolder addBall(float x, float y) {            OvalShape circle = new OvalShape();            circle.resize(BALL_SIZE, BALL_SIZE);            ShapeDrawable drawable = new ShapeDrawable(circle);            ShapeHolder shapeHolder = new ShapeHolder(drawable);            shapeHolder.setX(x - BALL_SIZE / 2);            shapeHolder.setY(y - BALL_SIZE / 2);            int red = (int) (Math.random() * 255);            int green = (int) (Math.random() * 255);            int blue = (int) (Math.random() * 255);            int color = 0xff000000 + red << 16 | green << 8 | blue;            Paint paint = drawable.getPaint();            int drakColor = 0xff000000 | red / 4 << 16 | green / 4 << 8 | blue /4;            RadialGradient gradient = new RadialGradient(37.5f, 12.5f, BALL_SIZE, color, drakColor,                    Shader.TileMode.CLAMP);            paint.setShader(gradient);            shapeHolder.setPaint(paint);            balls.add(shapeHolder);            return shapeHolder;        }        /**         * 将集合里的每个小球都绘制在屏幕上面         * @param canvas         */        @Override        protected void onDraw(Canvas canvas) {            for (ShapeHolder shapeHolder : balls) {                canvas.save();                canvas.translate(shapeHolder.getX(), shapeHolder.getY());                shapeHolder.getShape().draw(canvas);                canvas.restore();            }        }        @Override        public void onAnimationUpdate(ValueAnimator animation) {            this.invalidate();        }    }}
1 0
原创粉丝点击