在 bottomsheet 顶部创建带圆角的三角形

Create triangle with rounded corners at top of bottomsheet

我想在 android 设备的底页顶部创建一个带圆角的三角形,其宽度与父级相匹配

您可以使用带有自定义 ShapeAppearanceModelMaterialShapeDrawable 来实现此目的。

1. 获取最新的 Material Design Library 并将其添加到您的应用程序 grandle 依赖项中(实现 'com.google.android.material:material:1.4.0')

2. 在您的底部 Sheet xml 文件中定义一个空视图(例如:相对布局),它将成为底部的顶部Sheet。示例如下所示:

<?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. 最后创建您的自定义 ShapeAppearanceModel,仅在左上角使用圆角,并为 [=18= 使用自定义 EdgeTreatment ] 使用 ShapePath.quadToPoint 方法绘制上面的三角形,如下例所示:

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)

结果: