Sometimes in my practice I want to round view's background corners. Usually i use something like this (@drawable/bg_rounded)
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="16dp"/>
</shape>
But sometimes i need to round only one angle and do this programmatically
I create a test project to show the problem. 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 may be like
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
)
}
}
but unexpected behavior happens - corners are not rounded click to see picture
if i use background.cornerRadius it works predictable
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
// )
}
}
So my question is: what should I use to achieve dynamic adjustment of different radius of corners
CodePudding user response:
if i use background.cornerRadius it works predictable
It is because clipping
only supports rectangle, circle, or round rect.
When you use background.cornerRadius
it uses RoundRect
to draw, but when you use background.cornerRadii
it uses Path
to draw, and path clipping is not supported until API 33
. Check outline documentation.
You cannot use variable corners radius, but you can do a workaround to keep rounded corners at desired positions by using ViewOutlineProvider
and RoundRect
to draw the outline
. You can read more detailed answers about it here.