Skip to content

Instantly share code, notes, and snippets.

@vishvendra01
Last active July 31, 2021 16:55
Show Gist options
  • Save vishvendra01/a4f96f49fa399fa23d9811580a40cffb to your computer and use it in GitHub Desktop.
Save vishvendra01/a4f96f49fa399fa23d9811580a40cffb to your computer and use it in GitHub Desktop.
Animated HeartView using Canvas API

Animated HeartView Preview

Preview 1

package com.app.vaccinenotifier.view;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.concurrent.TimeUnit;
public class HeartView extends View {
private Path path;
private Paint heartPaint, progressPaint;
private RectF verticalFillRect;
private float verticalProgress = 1;
private int width, height;
private boolean showProgressText = false;
private Handler handler;
public HeartView(Context context) {
super(context);
init();
}
public HeartView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public HeartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
path = new Path();
heartPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
heartPaint.setColor(Color.RED); // Set with heart color
heartPaint.setStrokeWidth(10);
heartPaint.setStyle(Paint.Style.STROKE); // Fill with heart color
progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
progressPaint.setColor(Color.RED);
progressPaint.setStyle(Paint.Style.FILL);
verticalFillRect = new RectF();
handler = new Handler(Looper.getMainLooper());
}
public void setProgress(float progress){
if(progress < 0 || progress > 100){
throw new IllegalArgumentException("Please provide proper arguments");
}
verticalProgress = progress;
verticalFillRect.top = height - ((verticalProgress / 100) * height);
invalidate();
}
public void animateProgress(){
ValueAnimator animator = ValueAnimator.ofFloat(1, 100);
animator.setDuration(TimeUnit.SECONDS.toMillis(4));
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (Float) animation.getAnimatedValue();
setProgress(value);
}
});
animator.start();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int w = getMeasuredWidth();
int h = getMeasuredHeight();
setMeasuredDimension(Math.min(w, h), Math.min(w, h));
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width = w;
height = h;
path.moveTo(width/2, height);
path.cubicTo(-width/2, 0, width/2, -height/4, width/2, height/4);
path.moveTo(width/2, height);
path.cubicTo(width+ width/2, 0, width/2, -height/4, width/2, height/4);
verticalFillRect.left = 0;
verticalFillRect.right = width;
verticalFillRect.top = height - ((verticalProgress / 100) * height);
//verticalFillRect.top = height /2;
verticalFillRect.bottom = height;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.clipPath(path);
canvas.drawPath(path, heartPaint);
canvas.drawRect(verticalFillRect, progressPaint);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment