码迷,mamicode.com
首页 > 其他好文 > 详细

属性动画

时间:2015-03-03 00:00:45      阅读:357      评论:0      收藏:0      [点我收藏+]

标签:动画   属性动画   

属性(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();
        }
    }
}

属性动画

标签:动画   属性动画   

原文地址:http://blog.csdn.net/jing_unique_da/article/details/44025705

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!