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)
:
可以看到效果图和咋们想的一样,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即可,否则的话可能你跑不起来哦~
猜你喜欢:
原创不易,您的点赞就是对我最大的支持,留下您的点赞以及评论吧~