Android移动开发-属性动画的实现

Android移动开发-属性动画的实现,该示范了如何利用属性动画来控制“小球”掉落动画,该示例会监听用户在屏幕上的“触屏”时间,程序会在屏幕的触摸点绘制一个小球,并用动画控制该小球向下掉落。

MainActivity.java

package com.fukaimei.animatortest;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.LinearLayout;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    // 定义小球大小的常量
    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.container);
        // 设置该窗口显示MyAnimationView组件
        container.addView(new MyAnimationView(this));
    }
    public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener {

        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
        public MyAnimationView(Context context) {
            super(context);
            setBackgroundColor(Color.WHITE);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // 如果触碰事件不是按下、移动事件
            if (event.getAction() != MotionEvent.ACTION_DOWN &&
                    event.getAction() != MotionEvent.ACTION_MOVE) {
                return false;
            }
            //  在事件发生点添加一个小球(用一个圆形代表)
            ShapeHolder newBall = addBall(event.getX(), event.getY());
            // 计算小球下落动画开始时的y坐标
            float startY = newBall.getY();
            // 计算小球下落动画结束时的y坐标(落到屏幕最下方,就是屏幕高度减去小球高度)
            float endY = getHeight() - BALL_SIZE;
            // 获取屏幕高度
            float h = (float) getHeight();
            float eventY = event.getY();
            // 计算动画的持续时间
            int duration = (int) (FULL_TIME * ((h - eventY) / h));
            // 定义小球“落下”的动画:
            // 让newBall对象的y属性从事件发生点变化到屏幕最下方
            ValueAnimator fallAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY);
            // 设置fallAnim动画的持续时间
            fallAnim.setDuration(duration);
            // 设置fallAnim动画的插值方式:加速插值
            fallAnim.setInterpolator(new AccelerateInterpolator());
            // 为fallAnim动画添加监听器
            // 当ValueAnimator的属性值发生改变时,将会激发该监听器的事件监听方法
            fallAnim.addUpdateListener(this);
            // 定义对newBall对象的alpha属性执行从1到0的动画(即定义渐隐动画)
            ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
            // 设置动画持续时间
            fadeAnim.setDuration(250);
            // 为fadeAnim动画添加监听器
            fadeAnim.addListener(new AnimatorListenerAdapter() {

                // 当动画结束时
                @Override
                public void onAnimationEnd(Animator animation) {
                    // 动画结束时将该动画关联的ShapeHolder删除
                    balls.remove(((ObjectAnimator) animation).getTarget());
                }
            });
            // 为fadeAnim动画添加监听器
            // 当ValueAnimator的属性值发生改变时,将会激发该监听器的事件监听方法
            fadeAnim.addUpdateListener(this);
            // 定义一个AnimatorSet来组合动画
            AnimatorSet animatorSet = new AnimatorSet();
            // 指定在播放fadeAnim之前,先播放fallAnim动画
            animatorSet.play(fallAnim).before(fadeAnim);
            // 开始播放动画
            animatorSet.start();
            return true;
        }
        private ShapeHolder addBall(float x, float y) {
            // 创建一个椭圆
            OvalShape circle = new OvalShape();
            // 设置该椭圆的宽和高
            circle.resize(BALL_SIZE, BALL_SIZE);
            // 将椭圆包装成Drawable对象
            ShapeDrawable drawable = new ShapeDrawable(circle);
            // 创建一个ShapeHolder对象
            ShapeHolder shapeHolder = new ShapeHolder(drawable);
            // 设置ShapeHolder的x、y坐标
            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);
            // 将red、green、blue三个随机数组合成ARGB颜色
            int color = 0xff000000 + red << 16 | green << 8 | blue;
            // 获取drawable上关联的画笔
            Paint paint = drawable.getPaint();
            // 将red、green、blue三个随机数除以4得到商值组合成ARGB颜色
            int darkColor = 0xff000000 | red / 4 << 16
                    | green / 4 << 8 | blue / 4;
            // 创建圆形渐变
            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
                    BALL_SIZE, color, darkColor, Shader.TileMode.CLAMP);
            paint.setShader(gradient);
            // 为shapeHolder设置paint画笔
            shapeHolder.setPaint(paint);
            balls.add(shapeHolder);
            return shapeHolder;
        }

        @Override
        protected void onDraw(Canvas canvas) {
            // 遍历balls集合中的每个ShapeHolder对象
            for (ShapeHolder shapeHolder : balls) {
                // 保存canvas的当前坐标系统
                canvas.save();
                // 坐标变换:将画布坐标系统平移到shapeHolder的X、Y坐标处
                canvas.translate(shapeHolder.getX(), shapeHolder.getY());
                // 将shapeHolder持有的圆形绘制在Canvas上
                shapeHolder.getShape().draw(canvas);
                // 恢复Canvas坐标系统
                canvas.restore();
            }
        }

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            // 指定重绘该界面
            this.invalidate();
        }
    }
}


ShapeHolder.java

package com.fukaimei.animatortest;

import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.drawable.ShapeDrawable;

/**
 * Created by FuKaimei on 2017/9/17.
 */

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 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 ShapeDrawable getShape() {
        return shape;
    }

    public void setShape(ShapeDrawable shape) {
        this.shape = shape;
    }

    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
    }

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




源码下载地址:
http://download.csdn.net/download/fukaimei/9982420

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值