Android 轮子之点赞红心动画

废话不多说,直接上效果图:

效果图(1.1):
在这里插入图片描述

老套路先来分析:

  • 屏幕上有3个按钮,模仿点赞,关注与转发,点击点赞和转发的时候在他的上方弹出一❤
  • ❤颜色是随机的,向上飘移,并在2s之后消失
  • 随机5个❤

画❤

public class LoveView extends View {
  	 //❤半径
    private float rate = 5;
    //画笔
     private Paint paint = new Paint();
public LoveView(Context context) {
        this(context, null);
    }

    public LoveView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LoveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
    }
  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         ......
    }

   @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
		  // 重置画板
            path.reset();
            // 得到屏幕的长宽的一半
            // 路径的起始点
            path.moveTo(loveBean.pointF.x, loveBean.pointF.y - 5 * rate);
            // 根据心形函数画图
            for (double i = 0; i <= 2 * Math.PI; i += 0.001) {
                float x = (float) (16 * Math.sin(i) * Math.sin(i) * Math.sin(i));
                float y = (float) (13 * Math.cos(i) - 5 * Math.cos(2 * i) - 2 * Math.cos(3 * i) - Math.cos(4 * i));
                x *= rate;
                y *= rate;
                x = loveBean.pointF.x - x;
                y = loveBean.pointF.y - y;
                path.lineTo(x, y);
            }
            canvas.drawPath(path, paint);
      }
}


class LoveBean {
    //爱心的位置
    PointF pointF = new PointF(-100, -100);
}

大家不用纠结这段代码怎么写的,只要有网百度一下就能获取到绘制❤的函数,一套方法就出来了,这里大家只要知道的是 LoveBean类中的PointF pointF = new PointF();是控制的❤的位置,rate是控制的❤的半径即可

效果图(1.2):
在这里插入图片描述

初始化5个红心

public class LoveView extends View {
	//用来存放5个红心
	 List<LoveBean> mList = new ArrayList<>();
		......
		public LoveView(Context context, @Nullable AttributeSet attrs, int 	defStyleAttr) {
   	     super(context, attrs, defStyleAttr);
        //初始化爱心
        initData(300, 300);
    }
    
	/**
     * @param x 初始化x位置
     * @param y 初始化y位置
     *          用来初始化爱心
     */
    private void initData(float x, float y) {
        mList.clear();
        for (int i = 0; i < 5; i++) {
            LoveBean loveBean = new LoveBean();
            loveBean.pointF.x = x;
            loveBean.pointF.y = y ;
            mList.add(loveBean);
        }
    }
	@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //循环绘制爱心
        for (int j = 0; j < mList.size(); j++) {
            LoveBean loveBean = mList.get(j);
            // 重置画板
            path.reset();
            // 得到屏幕的长宽的一半
            // 路径的起始点
            path.moveTo(loveBean.pointF.x, loveBean.pointF.y - 5 * rate);
            // 根据心形函数画图
            for (double i = 0; i <= 2 * Math.PI; i += 0.001) {
                float x = (float) (16 * Math.sin(i) * Math.sin(i) * Math.sin(i));
                float y = (float) (13 * Math.cos(i) - 5 * Math.cos(2 * i) - 2 * Math.cos(3 * i) - Math.cos(4 * i));
                x *= rate;
                y *= rate;
                x = loveBean.pointF.x - x;
                y = loveBean.pointF.y - y;
                path.lineTo(x, y);
            }
            canvas.drawPath(path, paint);
        }
    }
}

效果图(1.3):
在这里插入图片描述
当然,在这里❤不会有什么变化,即使他有5个,因为他的位置半径都是一样的…

接下来让他不要重合在一起,稍微有一点偏移,并添加随机颜色

红心随机颜色以及偏移

class LoveBean {
    //爱心的位置
    PointF pointF = new PointF(-100, -100);
    //爱心的偏移位置
    PointF deviation = new PointF();
    //爱心的颜色
    int color ;
}

public class LoveView extends View {
	//自定义颜色
	private final int[] colors = {Color.CYAN, Color.YELLOW,  Color.LTGRAY, Color.GREEN, Color.RED};
	//随机数
    public Random random = new Random();
    
  public LoveView(Context context, @Nullable AttributeSet attrs, int 	defStyleAttr) {
  	 super(context, attrs, defStyleAttr);
    //初始化爱心
        initData(300,300);
  }
	 /**
     * @param x 初始化x位置
     * @param y 初始化y位置
     *          用来初始化爱心
     */
    private void initData(float x, float y) {
        mList.clear();
        for (int i = 0; i < 5; i++) {
            LoveBean loveBean = new LoveBean();
            //设置随颜色
            loveBean.color.add(colors[random.nextInt(colors.length)]);

            /**
             * 爱心的偏移位置
             * random.nextDouble()随机的是0-1之间的小数
             * random.nextInt(5); 随机的是1-5之间的整数
             */
            loveBean.deviation.x = (float) (random.nextDouble() );
            loveBean.deviation.y = random.nextInt(5);

            //现在的位置 = 手指点击的位置 + 偏移的位置  (偏移的位置是为了有一种参差不齐的感觉!)
            loveBean.pointF.x = x + loveBean.deviation.x ;
            loveBean.pointF.y = y + loveBean.deviation.y ;

            mList.add(loveBean);
        }
    }
	 @Override
    protected void onDraw(Canvas canvas) {
			//循环绘制爱心
        for (int j = 0; j < mList.size(); j++) {
            LoveBean loveBean = mList.get(j);
            //设置颜色
            paint.setColor(loveBean.color);
            // 重置画板
            path.reset();
            // 得到屏幕的长宽的一半
            // 路径的起始点
            Log.i("szjonDraw",loveBean.pointF.x+"\t"+(loveBean.pointF.y - 5 * rate));
            path.moveTo(loveBean.pointF.x, loveBean.pointF.y - 5 * rate);
            // 根据心形函数画图
            for (double i = 0; i <= 2 * Math.PI; i += 0.001) {
                float x = (float) (16 * Math.sin(i) * Math.sin(i) * Math.sin(i));
                float y = (float) (13 * Math.cos(i) - 5 * Math.cos(2 * i) - 2 * Math.cos(3 * i) - Math.cos(4 * i));
                x *= rate;
                y *= rate;
                x = loveBean.pointF.x - x;
                y = loveBean.pointF.y - y;
                path.lineTo(x, y);
            }
            canvas.drawPath(path, paint);
        }
	}
}

效果图(1.4):
里插入图片描述](https://img-blog.csdnimg.cn/20201204105709978.png)
可以看到效果图和咋们想的一样,5个❤叠加到一起,并且还有一点点的偏移

来看看Log打印出的每个❤的位置;

Log图(2.1):
在这里插入图片描述

添加动画

接下来给红心添加动画,让他动起来即可

private void initLove() {
        if (valueAnimator != null) {
            //移除上一个valueAnimator
            valueAnimator.removeAllUpdateListeners();

        }
        valueAnimator = ValueAnimator.ofInt(255, 100, 0);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                animatedValue = (int) animation.getAnimatedValue();
                //设置向上移动
                initAnimator();
                //设置透明度
                for (int i = 0; i < mList.size(); i++) {
                    mList.get(i).alpha = animatedValue;
                }
            }
        });
        valueAnimator.setDuration(2000);
        valueAnimator.start();
    }


	 //向上移动动画
    private void initAnimator() {
        for (int i = 0; i < mList.size(); i++) {
            LoveBean loveBean = mList.get(i);

			//新的移动位置 = 当前位置 + 偏移位置 
			//因为是向上移动,所以Y是-去偏移位置
            float dx = loveBean.pointF.x + loveBean.deviation.x;
            float dy = loveBean.pointF.y - loveBean.deviation.y;
            loveBean.pointF = new PointF(dx, dy);
        }
        invalidate();
    }

走到这里红心就可以根据位置来弹出向上移动的动画啦~

接下来给按钮设置点击事件达到刚开头的效果

	 //点赞按钮
        bt1 .setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loveView.addAnimation(bt1);
            }
        });

        //转发按钮
        bt3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loveView.addAnimation(bt3);
            }
        });


 public void addAnimation(View bt){
        //重新初始化Love和现在的位置
        initData(bt.getX() + bt.getMeasuredWidth() / 2, bt.getY()  - bt.getMeasuredHeight() / 2 );
        //重新初始化Love动画
        initLove();
        //重新绘制
        invalidate();
    }

来看看最终效果吧:

效果图(1.5)
在这里插入图片描述

还可以通过setLoveNumber()设置爱心的数量,setLoveRadius()设置爱心的半径

  //点赞按钮
        bt1 .setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loveView.setLoveNumber(10);
                loveView.setLoveRadius(10);
                loveView.addAnimation(bt1);
            }
        });

        View bt3 = findViewById(R.id.bt3);
        //转发按钮
        bt3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                loveView.setLoveNumber(1);
                loveView.setLoveRadius(5);
                loveView.addAnimation(bt3);
            }
        });

效果图(1.6):

在这里插入图片描述

注:
我的项目之中有和Flutter混合开发的东西,如果你没有Flutter下载LoveView即可,否则的话可能你跑不起来哦~

完整代码

猜你喜欢:

Android 轮子之下雪效果

原创不易,您的点赞就是对我最大的支持,留下您的点赞以及评论吧~

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

s10g

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值