Android下红包雨的实现

本文介绍了如何在Android项目中实现红包雨动画效果,通过创建红包实体类、自定义View并设置相关事件来达成这一效果。详细过程包括view的初始化、绘制、开始结束事件以及点击事件的设定。
摘要由CSDN通过智能技术生成

最近做项目的时候,需要做一个类似下红包雨的效果。经过自己的反复研究,发现使用动画是最合适的。下面贴出这种实现效果的流程

首先看一下红包雨的简单效果图

在这里插入图片描述

  1. 首先创建一个用来初始化红包相关的值的红包实体类
public class RedPacket {
    public float x, y;
    public float rotation;
    public float speed;
    public float rotationSpeed;
    public int width, height;
    public Bitmap bitmap;
    public int money;
    public boolean isRealRed;

    public RedPacket(Context context, Bitmap originalBitmap, int speed, float maxSize, float minSize, int viewWidth) {
        //获取一个显示红包大小的倍数
        double widthRandom = Math.random();
        if (widthRandom < minSize || widthRandom > maxSize) {
            widthRandom = maxSize;
        }
        //红包的宽度
        width = (int) (originalBitmap.getWidth() * widthRandom);
        //红包的高度
        height = width * originalBitmap.getHeight() / originalBitmap.getWidth();
        int mWidth = (viewWidth == 0) ? context.getResources().getDisplayMetrics().widthPixels : viewWidth;
        //生成红包bitmap
        bitmap = Bitmap.createScaledBitmap(originalBitmap, width, height, true);
        originalBitmap.recycle();
        Random random = new Random();
        //红包起始位置x:[0,mWidth-width]
        int rx = random.nextInt(mWidth) - width;
        x = rx <= 0 ? 0 : rx;
        //红包起始位置y
        y = -height;
        //初始化该红包的下落速度
        this.speed = speed + (float) Math.random() * 1000;
        //初始化该红包的初始旋转角度
        rotation = (float) Math.random() * 180 - 90;
        //初始化该红包的旋转速度
        rotationSpeed = (float) Math.random() * 90 - 45;
        //初始化是否为中奖红包
        isRealRed = isRealRedPacket();
    }

    /**
     * 判断当前点是否包含在区域内
     */
    public boolean isContains(float x, float y) {
        //稍微扩大下点击的区域
        return this.x-50 < x && this.x +50 + width > x
                && this.y-50 < y && this.y+50 + height > y;
    }

    /**
     * 随机 是否为中奖红包
     */
    public boolean isRealRedPacket() {
        Random random = new Random();
        int num = random.nextInt(10) + 1;
        //如果[1,10]随机出的数字是2的倍数 为中奖红包
        if (num % 2 == 0) {
            money = num*2;//中奖金额
            return true;
        }
        return false;
    }

    /**
     * 回收图片
     */
    public void recycle() {
        if (bitmap!= null && !bitmap.isRecycled()){
            bitmap.recycle();
        }
    }
}

  1. 接下来就要需要使用自定义view来实现效果
    (1)view初始化
 public RedPacketTest(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RedPacketStyle);
        //获取xml中配置的view的style属性,如下落红包数量,下落的基础速度,以及红包图片的最大最小范围
        count = typedArray.getInt(R.styleable.RedPacketStyle_count, 20);
        speed = typedArray.getInt(R.styleable.RedPacketStyle_speed, 20);
        minSize = typedArray.getFloat(R.styleable.RedPacketStyle_min_size, 0.5f);
        maxSize = typedArray.getFloat(R.styleable.RedPacketStyle_max_size, 1.2f);
        typedArray.recycle();
        init();
    }


    /**
     * 初始化
     */
    private void init() {
        //初始化画笔
        paint = new Paint();
        paint.setFilterBitmap(true);
        paint.setDither(true);
        paint.setAntiAlias(true);
        //创建一个属性动画,通过属性动画来控制刷新红包下落的位置
        animator = ValueAnimator.ofFloat(0, 1);
       //绘制view开启硬件加速
        setLayerType(View.LAYER_TYPE_HARDWARE, null);
      //初始化属性动画
        initAnimator();
    }

    private void initAnimator() {
        //每次动画更新的时候,更新红包下落的坐标值
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                long nowTime = System.currentTimeMillis();
                //获取两次动画更新之间的时间,以此来计算下落的高度
                float secs = (float) (nowTime - prev
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值