Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cutting the corners off a layout

I have a layout in android that needs to be a certain shape, i.e. this: rectangle with clipped corners

where the corners are cut off. Is there a way of doing this programatically without setting the background of the layout to the image? I'm looking to keep the app size as small as possible so minimising the number of drawables in the app is a must.

like image 590
MichaelStoddart Avatar asked Jun 24 '15 10:06

MichaelStoddart


2 Answers

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.shapes.Shape;

public class WeirdShape extends Shape {
    private static final int    COLOUR       = Color.BLACK;
    private static final float  STROKE_WIDTH = 1.0f;
    private static final float  CORNER = 35.0f;

    private final Paint border = new Paint();
    private final Path  path;  

    public WeirdShape() {
       path   = new Path();

        border.setColor      (COLOUR);
        border.setStyle      (Paint.Style.FILL);
        border.setStrokeWidth(STROKE_WIDTH);
        border.setAntiAlias  (true);
        border.setDither     (true);
        border.setStrokeJoin (Paint.Join.ROUND);  
        border.setStrokeCap  (Paint.Cap.ROUND);  
    }

    @Override
    protected void onResize(float width, float height) {
        super.onResize(width, height);

        float dx = STROKE_WIDTH/2.0f;
        float dy = STROKE_WIDTH/2.0f;
        float x  = dx;
        float y  = dy;
        float w  = width  - dx;
        float h  = height - dy;

        //RectF arc = new RectF(x,h-2*CORNER,x+2*CORNER,h);

        path.reset();
        path.moveTo(x + CORNER,y);
        path.lineTo(w - CORNER,y);
        path.lineTo(w,y + CORNER);
        path.lineTo(w, h);
        path.lineTo(x + CORNER,h);
       // path.arcTo (arc,90.0f,90.0f);
        path.lineTo(dx,h - CORNER);
        path.lineTo(dx,y);//path.lineTo(dx,y + CORNER);
        path.close();
    }


    @Override
    public void draw(Canvas canvas, Paint paint) {
        // TODO Auto-generated method stub
        canvas.drawPath(path,border);
    }
}

and then use the custom Shape in a ShapeDrawable as the background Drawable:

view.setBackground(new ShapeDrawable(new WeirdShape()));

Which looks something like:

like image 198
Shishir Shetty Avatar answered Nov 08 '22 11:11

Shishir Shetty


You can use the ShapeAppearanceModel provided by the Material Components Library:

    <LinearLayout
        android:id="@+id/layout"
        ..>

with:

    val radius = resources.getDimension(R.dimen.cornerSize16)

    val linearLayout = findViewById<LinearLayout>(R.id.layout)
    val shapeAppearanceModel = ShapeAppearanceModel()
        .toBuilder()
        .setTopRightCorner(CornerFamily.CUT, radius)
        .setBottomLeftCorner(CornerFamily.CUT, radius)
        .build()

    val shapeDrawable = MaterialShapeDrawable(shapeAppearanceModel)
    ViewCompat.setBackground(linearLayout, shapeDrawable)

enter image description here

like image 25
Gabriele Mariotti Avatar answered Nov 08 '22 10:11

Gabriele Mariotti