
In this article, we’ll explore drawRoundRect method of Jetpack Compose Canvas.
Prerequisites:
Note: Instead of Canvas, you can create round rectangles using the Box and Shape APIs.
For this article, create an empty Jetpack Compose project and open MainActivity.kt. Create a composable called MyUI() and call it from the onCreate().
// add the following packages
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.unit.dp
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
YourProjectNameTheme(darkTheme = false) {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
MyUI()
}
}
}
}
}
}
@Composable
fun MyUI() {
}
We’ll write our code in the MyUI().
drawRoundRect helps us to draw a rectangle with rounded corners. It takes multiple parameters:
fun drawRoundRect(
color: Color,
topLeft: Offset = Offset.Zero,
size: Size = this.size.offsetSize(topLeft),
cornerRadius: CornerRadius = CornerRadius.Zero,
alpha: Float = 1.0f,
style: DrawStyle = Fill,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
color – Color of the rectangle.
topLeft – Offset value. Look at the Canvas article for more information.
size – Size of the rectangle.
cornerRadius – Corner radius of the rounded rectangle, negative radii values are clamped to 0.
alpha – Opacity value of the rectangle. It ranges from 0f to 1f. 0f represents fully transparent, and 1f represents fully opaque.
style – Specifies whether the rounded rectangle is stroked or filled in.
colorFilter – It is used to modify each pixel of the rectangle.
blendMode – Blending algorithm to be applied to the rectangle when it is drawn.
Let us understand the parameters with examples.
First, let’s create a Canvas of size 300.dp.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
}
}
Output:

Here is a simple rectangle:
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRoundRect(
color = Color.Red,
size = Size(width = 100.dp.toPx(), height = 64.dp.toPx())
)
}
}
Output:

Note: If you don’t specify the size, it occupies the whole canvas.
Currently, it has sharp corners. We can use the cornerRadius parameter to make them round. The CornerRadius method takes two parameters – x and y and constructs a radius based on them.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRoundRect(
color = Color.Red,
size = Size(width = 100.dp.toPx(), height = 64.dp.toPx()),
cornerRadius = CornerRadius(x = 36.dp.toPx(), y = 36.dp.toPx())
)
}
}
Output:

Let us change its position to the center of the canvas. We have to use the topLeft parameter and Offset function.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRoundRect(
color = Color.Red,
size = Size(width = 100.dp.toPx(), height = 64.dp.toPx()),
cornerRadius = CornerRadius(x = 36.dp.toPx(), y = 36.dp.toPx()),
topLeft = Offset(x = 150.dp.toPx(), y = 150.dp.toPx())
)
}
}
Output:

It is not exactly in the middle. If you observe it closely, the top left corner of the rectangle is kept at the center. So, we need to move the rectangle to the left by half of its width and up by half of its height.
The new offset coordinates become:
x = (canvas width / 2) - (rectangle width / 2)
= (300 / 2) - (100 / 2)
= 100
y = (canvas height / 2) - (rectangle height / 2)
= (300 / 2) - (64 / 2)
= 118
In the above code, change the topLeft parameter.
topLeft = Offset(x = 100.dp.toPx(), y = 118.dp.toPx())
Output:

Note: Do not directly use pixels. Always convert dp to pixels to support all the screen densities.
We can create a rectangle with stroke by using the style parameter.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRoundRect(
color = Color.Red,
size = Size(width = 100.dp.toPx(), height = 64.dp.toPx()),
cornerRadius = CornerRadius(x = 36.dp.toPx(), y = 36.dp.toPx()),
topLeft = Offset(x = 100.dp.toPx(), y = 118.dp.toPx()),
style = Stroke(width = 4.dp.toPx())
)
}
}
Output:

Instead of color, we can also pass brush to create gradient effects.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRoundRect(
brush = Brush.horizontalGradient(colors = listOf(Color.Cyan, Color.Magenta)),
size = Size(width = 100.dp.toPx(), height = 64.dp.toPx()),
cornerRadius = CornerRadius(x = 36.dp.toPx(), y = 36.dp.toPx()),
topLeft = Offset(x = 100.dp.toPx(), y = 118.dp.toPx())
)
}
}
Output:

This is about the drawRoundRect method of Jetpack Compose Canvas. I hope you have learned something new. If you have any doubts, comment below.
Related Articles: