Hexagonal ImageView Rounded corners

1000 Views Asked by At

enter image description here

Hi I want rounded corners as shown in above image. I have managed to make hexagonal ImageView. But I am not able to round the corners. Please help. I am copying the code here if anyone wants to take a look. I have tried giving the arc as used in oval ImageView but its not working. I am a newbie to android. Any help will be highly appreciated.

public class HexagonImageView extends ImageView {

private Path hexagonPath;
private Path hexagonBorderPath;
private float radius;
private Bitmap image;
private int viewWidth;
private int viewHeight;
private Paint paint;
private BitmapShader shader;
private Paint paintBorder;
private int borderWidth = 5;

public HexagonImageView(Context context) {
    super(context);
    setup();
}

public HexagonImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setup();
}

public HexagonImageView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setup();
}

private void setup() {
    paint = new Paint();
    paint.setAntiAlias(true);

    paintBorder = new Paint();
    setBorderColor(Color.WHITE);
    paintBorder.setAntiAlias(true);
    this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
    paintBorder.setShadowLayer(4.0f, 1.0f, 1.0f, Color.BLACK);

    hexagonPath = new Path();
    hexagonBorderPath = new Path();

}

public void setRadius(float r) {
    this.radius = r;
    calculatePath();
    this.invalidate();
}

public void setBorderWidth(int borderWidth)  {
    this.borderWidth = borderWidth;
    this.invalidate();
}

public void setBorderColor(int borderColor)  {
    if (paintBorder != null)
        paintBorder.setColor(borderColor);

    this.invalidate();
}

private void calculatePath() {

    float triangleHeight = (float) (Math.sqrt(3) * radius / 2);
    float centerX = viewWidth/2;
    float centerY = viewHeight/2;

    hexagonBorderPath.moveTo(centerX, centerY + radius);
    hexagonBorderPath.lineTo(centerX - triangleHeight, centerY + radius/2);
    hexagonBorderPath.lineTo(centerX - triangleHeight, centerY - radius/2);
    hexagonBorderPath.lineTo(centerX, centerY - radius);
    hexagonBorderPath.lineTo(centerX + triangleHeight, centerY - radius/2);
    hexagonBorderPath.lineTo(centerX + triangleHeight, centerY + radius/2);
    hexagonBorderPath.moveTo(centerX, centerY + radius);

    float radiusBorder = radius - borderWidth;    
    float triangleBorderHeight = (float) (Math.sqrt(3) * radiusBorder / 2);

    hexagonPath.moveTo(centerX, centerY + radiusBorder);
    hexagonPath.lineTo(centerX - triangleBorderHeight, centerY + radiusBorder/2);
    hexagonPath.lineTo(centerX - triangleBorderHeight, centerY - radiusBorder/2);
    hexagonPath.lineTo(centerX, centerY - radiusBorder);
    hexagonPath.lineTo(centerX + triangleBorderHeight, centerY - radiusBorder/2);
    hexagonPath.lineTo(centerX + triangleBorderHeight, centerY + radiusBorder/2);
    hexagonPath.moveTo(centerX, centerY + radiusBorder);

    this.invalidate();
}

private void loadBitmap()  {
    BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();

    if (bitmapDrawable != null)
        image = bitmapDrawable.getBitmap();
}

@SuppressLint("DrawAllocation")
@Override
public void onDraw(Canvas canvas){
    super.onDraw(canvas);

    loadBitmap();

    // init shader
    if (image != null) {

        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

        shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), true), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        paint.setShader(shader);

        canvas.drawPath(hexagonBorderPath, paintBorder);
        canvas.drawPath(hexagonPath, paint);
        canvas.clipPath(hexagonPath, Region.Op.DIFFERENCE);
    }

}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int width = measureWidth(widthMeasureSpec);
    int height = measureHeight(heightMeasureSpec, widthMeasureSpec);

    viewWidth = width - (borderWidth * 2);
    viewHeight = height - (borderWidth * 2);

    radius = height / 2 - borderWidth;

    calculatePath();

    setMeasuredDimension(width, height);
}

private int measureWidth(int measureSpec)   {
    int result = 0;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    if (specMode == MeasureSpec.EXACTLY)  {
        result = specSize;
    }
    else {
        result = viewWidth;
    }

    return result;
}

private int measureHeight(int measureSpecHeight, int measureSpecWidth)  {
    int result = 0;
    int specMode = MeasureSpec.getMode(measureSpecHeight);
    int specSize = MeasureSpec.getSize(measureSpecHeight);

    if (specMode == MeasureSpec.EXACTLY) {
        result = specSize;
    }
    else {
        result = viewHeight;
    }

    return result;
}
}
2

There are 2 best solutions below

2
On

You need to replace your hexagonPath.lineTo commands with hexagonPath.cubicTo or hexagonPath.quadTo. Personally, I find the latter easy to work with. Like your line draws, both draw from the last point, but, respectively, they let you specify coordinates for 2 or 1 control points, plus the destination point. The control points will cause the bowing effect between plot points.

If it sounds like too much work (it's easier than it sounds), there is a library for your exact requirement referenced in this answer.

0
On

i used this

and i made as like yours.just modify corner radius and angle to get what you want.