Skip to content

Instantly share code, notes, and snippets.

@enriquebautista
Created September 11, 2018 23:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enriquebautista/e3d4b8d0801ea4fb77cd7dbd813df67b to your computer and use it in GitHub Desktop.
Save enriquebautista/e3d4b8d0801ea4fb77cd7dbd813df67b to your computer and use it in GitHub Desktop.
package app.pasaporte.ui.widget;
import android.content.Context;
import android.graphics.Path;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import app.pasaporte.ui.widget.shapeofview.ClipPathManager;
import app.pasaporte.ui.widget.shapeofview.ShapeOfView;
public class CutoutTicketView extends ShapeOfView {
private static final int DEFAULT_SCALLOP_RADIUS = 10; //dp
private static final int DEFAULT_CORNER_RADIUS = 4; //dp
private static final float DEFAULT_SHADOW_BLUR_RADIUS = 6f; //dp
private RectF roundedCornerArc = new RectF();
private RectF scallopCornerArc = new RectF();
private int mScallopRadius;
private int mCornerRadius;
private float mShadowBlurRadius;
public CutoutTicketView(@NonNull Context context) {
this(context, null);
}
public CutoutTicketView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CutoutTicketView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final int density = (int) context.getResources().getDisplayMetrics().density;
mScallopRadius = DEFAULT_SCALLOP_RADIUS * density;
mCornerRadius = DEFAULT_CORNER_RADIUS * density;
setShadowBlurRadius(DEFAULT_SHADOW_BLUR_RADIUS * density);
super.setClipPathCreator(new ClipPathManager.ClipPathCreator() {
@Override
public Path createClipPath(int width, int height) {
float left = getPaddingLeft() + mShadowBlurRadius;
float right = getWidth() - getPaddingRight() - mShadowBlurRadius;
float top = getPaddingTop() + (mShadowBlurRadius / 2);
float bottom = getHeight() - getPaddingBottom();
return generatePath(left, right, top, bottom);
}
@Override
public boolean requiresBitmap() {
return false;
}
});
}
private Path generatePath(float left, float right, float top, float bottom) {
final Path path = new Path();
//top rounded corners
path.arcTo(getTopLeftCornerRoundedArc(top, left), 180.0f, 90.0f, false);
path.lineTo(left + mCornerRadius, top);
path.lineTo(right - mCornerRadius, top);
path.arcTo(getTopRightCornerRoundedArc(top, right), -90.0f, 90.0f, false);
//bottom scallop corners
path.arcTo(getBottomRightCornerScallopArc(bottom, right), 270.0f, -90.0f, false);
path.lineTo(right - mScallopRadius, bottom);
path.lineTo(left + mScallopRadius, bottom);
path.arcTo(getBottomLeftCornerScallopArc(left, bottom), 0.0f, -90.0f, false);
path.close();
return path;
}
private RectF getTopLeftCornerRoundedArc(float top, float left) {
roundedCornerArc.set(left, top, left + mCornerRadius * 2, top + mCornerRadius * 2);
return roundedCornerArc;
}
private RectF getTopRightCornerRoundedArc(float top, float right) {
roundedCornerArc.set(right - mCornerRadius * 2, top, right, top + mCornerRadius * 2);
return roundedCornerArc;
}
private RectF getBottomLeftCornerScallopArc(float left, float bottom) {
scallopCornerArc.set(left - mScallopRadius, bottom - mScallopRadius, left + mScallopRadius, bottom + mScallopRadius);
return scallopCornerArc;
}
private RectF getBottomRightCornerScallopArc(float bottom, float right) {
scallopCornerArc.set(right - mScallopRadius, bottom - mScallopRadius, right + mScallopRadius, bottom + mScallopRadius);
return scallopCornerArc;
}
private void setShadowBlurRadius(float elevation) {
float maxElevation = dpToPx(24f);
mShadowBlurRadius = Math.min(25f * (elevation / maxElevation), 25f);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment