clipToOutline 与 cornerRadii 与背景

clipToOutline with cornerRadii with background

在我的练习中,有时我想把视图的背景角弄圆。 通常我使用这样的东西 (@drawable/bg_rounded)

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="16dp"/>
</shape>

但有时我只需要倒圆一个角度并以编程方式执行此操作

我创建了一个测试项目来展示这个问题。 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:layout_margin="20dp"
    android:background="@drawable/bg_rounded">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/purple_200"/>

</FrameLayout>

MainActivity class 可能像

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val container = findViewById<FrameLayout>(R.id.container)
        container.clipToOutline = true
        val background: GradientDrawable =
            container.background.mutate() as? GradientDrawable ?: return
        background.cornerRadii = floatArrayOf(
            20F, 20F, 20F, 20F,
            20F, 20F, 20F, 20F
        )
    }
}

但发生了意想不到的行为 - 边角不是圆角 click to see picture

如果我使用 background.cornerRadius 它可以预测

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val container = findViewById<FrameLayout>(R.id.container)
        container.clipToOutline = true
        val background: GradientDrawable =
            container.background.mutate() as? GradientDrawable ?: return
        background.cornerRadius = 20F
//        background.cornerRadii = floatArrayOf(
//            20F, 20F, 20F, 20F,
//            20F, 20F, 20F, 20F
//        )
    }
}

click to see picture

所以我的问题是:我应该用什么来实现不同半径角的动态调整

if i use background.cornerRadius it works predictable

因为clipping只支持矩形,圆形,圆角矩形

使用background.cornerRadius时使用RoundRect绘制,使用background.cornerRadii时使用Path绘制,不支持路径裁剪直到API 33Check outline documentation.

您不能使用可变圆角半径,但您可以通过使用 ViewOutlineProviderRoundRect 绘制 outline 来使圆角保持在所需位置。您可以阅读有关它的更详细的答案 .