Create triangle with rounded corners at top of bottomsheet

Viewed 240

I want to create a triangle with rounded corners at top of my bottomsheet in android device with width as match parent

enter image description here

1 Answers

You can achieve this using a MaterialShapeDrawable with a custom ShapeAppearanceModel.

1. Get the latest Material Design Library and add it into your app grandle dependencies (implementation 'com.google.android.material:material:1.4.0')

2. In your Bottom Sheet xml file define an empty View (eg: a Relative Layout) which will be the top of your Bottom Sheet. A sample will be like below:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/bottomSheetParentRL"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white">

    <RelativeLayout
        android:id="@+id/relativeLayout"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_alignParentTop="true"/>
    
</RelativeLayout>

3. Finally create your custom ShapeAppearanceModel with Rounded Corners only to the Top Left Side and use a custom EdgeTreatment for the TopEdge to draw the above triangle shape using the ShapePath.quadToPoint method like in the below example:

JAVA:

//get the Relative Layout or any other View
RelativeLayout relativeLayout = findViewById(R.id.relativeLayout);

//set the top left corner radius and bottom Y margin in pixels
int topLeftCornerRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
int bottomYMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25, getResources().getDisplayMetrics());

//create a new ShapeAppearanceModel
ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
        .toBuilder()
        .setTopLeftCorner(CornerFamily.ROUNDED, topLeftCornerRadius)
        .setTopRightCorner(CornerFamily.ROUNDED, 0)
        .setBottomLeftCorner(CornerFamily.ROUNDED, 0)
        .setBottomRightCorner(CornerFamily.ROUNDED, 0)
        .setTopEdge(new EdgeTreatment(){
            @Override public void getEdgePath(float length, float center, float interpolation, @NonNull ShapePath shapePath) {
                shapePath.quadToPoint(0, 0, length, relativeLayout.getLayoutParams().height - bottomYMargin);
            }
         })
        .build();

//create a new MaterialShapeDrawable based on above ShapeAppearanceModel and sets it color
MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel);
shapeDrawable.setFillColor(ContextCompat.getColorStateList(this, android.R.color.holo_blue_light));

//finally use the ViewCompat static method to draw the above shapeDrawable to relativeLayout
ViewCompat.setBackground(relativeLayout, shapeDrawable);

KOTLIN:

//get the Relative Layout or any other View
val relativeLayout = findViewById<RelativeLayout>(R.id.relativeLayout)

//set the top left corner radius and bottom Y margin in pixels
val topLeftCornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, resources.displayMetrics).toInt()
val bottomYMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25f, resources.displayMetrics).toInt()

//create a new ShapeAppearanceModel
val shapeAppearanceModel = ShapeAppearanceModel()
        .toBuilder()
        .setTopLeftCorner(CornerFamily.ROUNDED, topLeftCornerRadius.toFloat())
        .setTopRightCorner(CornerFamily.ROUNDED, 0f)
        .setBottomLeftCorner(CornerFamily.ROUNDED, 0f)
        .setBottomRightCorner(CornerFamily.ROUNDED, 0f)
        .setTopEdge(object : EdgeTreatment() {
            override fun getEdgePath(length: Float, center: Float, interpolation: Float, shapePath: ShapePath) {
                shapePath.quadToPoint(0f, 0f, length, (relativeLayout.layoutParams.height - bottomYMargin).toFloat())
            }
        })
        .build()

//create a new MaterialShapeDrawable based on above ShapeAppearanceModel and sets it color
val shapeDrawable = MaterialShapeDrawable(shapeAppearanceModel)
shapeDrawable.fillColor = ContextCompat.getColorStateList(this, android.R.color.holo_blue_light)

//finally use the ViewCompat static method to draw the above shapeDrawable to relativeLayout
ViewCompat.setBackground(relativeLayout, shapeDrawable)

Result:

shape

Related