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.
