
drawRect() method helps us to draw a rectangle in Jetpack Compose Canvas. Today, we are going to explore it with the help of examples.
Note: Instead of Canvas, you can create rectangles using the Box and Shape APIs.
For this article, create an empty Jetpack Compose project and open MainActivity. Add a composable called MyUI() and call it from the onCreate() method.
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.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 will write our code in the MyUI().
Canvas drawRect() Method:
fun drawRect(
color: Color,
topLeft: Offset = Offset.Zero,
size: Size = this.size.offsetSize(topLeft),
alpha: Float = 1.0f,
style: DrawStyle = Fill,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
color – Color of the rectangle. We can set the color in different ways.
topLeft – It is used to adjust the rectangle position.
size – Size of the rectangle.
alpha – Opacity level. It ranges from from 0.0f to 1.0f, 0.0f represents fully transparent and 1.0f represents fully opaque.
style – If the rectangle is filled or stroked (border applied).
colorFilter – It is used for modifying each pixel.
blendMode – It is the algorithm to use when painting on the canvas.
Here is a simple rectangle:
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRect(color = Color.Yellow)
}
}
Output:

If we don’t mention the size, it fills the whole canvas. Let’s set the size.
Rectangle Size:
We can set the size using the size parameter.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRect(
color = Color.Yellow,
size = Size(width = 160.dp.toPx(), height = 100.dp.toPx())
)
}
}
Output:

Note: Whenever you want to set the size, use dp.toPx() instead of float values. It ensures that your UI is consistent across all the screen densities.
Rectangle Position:
We can adjust the position by using the topLeft parameter. We need to pass an Offset object by using the Offset() function. It takes x and y coordinates.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRect(
color = Color.Yellow,
size = Size(width = 160.dp.toPx(), height = 100.dp.toPx()),
topLeft = Offset(x = 40.dp.toPx(), y = 60.dp.toPx())
)
}
}
Output:

The topLeft parameter sets the coordinates to the top left corner of the rectangle. In the above example, the top left corner is placed at (40.dp, 60.dp).
Let’s place it exactly at the center of the canvas. The canvas size is 300.dp. So, set the x and y coordinates to 150.dp.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRect(
color = Color.Yellow,
size = Size(width = 160.dp.toPx(), height = 100.dp.toPx()),
topLeft = Offset(x = 150.dp.toPx(), y = 150.dp.toPx())
)
}
}
Output:

Note: If the size of the canvas’ children is bigger than canvas’, they will cross the canvas’ borders. That is why some portion of the rectangle is outside the canvas.
The rectangle is not exactly at the center. Like I said before the top left corner of the rectangle is placed at (150.dp, 150.dp). We actually need to place the center of the rectangle at (150.dp, 150.dp). For that, we can calculate the top left coordinates like this:
x = (Canvas width / 2) - (rectangle width / 2)
= (300 / 2) - (160 / 2)
= 150 - 80
= 70
y = (Canvas height / 2) - (rectangle height / 2)
= (300 / 2) - (100 / 2)
= 150 - 50
= 100
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRect(
color = Color.Yellow,
size = Size(width = 160.dp.toPx(), height = 100.dp.toPx()),
topLeft = Offset(x = 70.dp.toPx(), y = 100.dp.toPx())
)
}
}
Output:

Rectangle with Border:
With the help of the style parameter, we can create a stroked rectangle. The Stroke() method takes the border width as a parameter.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRect(
color = Color.Yellow,
size = Size(width = 160.dp.toPx(), height = 100.dp.toPx()),
topLeft = Offset(x = 70.dp.toPx(), y = 100.dp.toPx()),
style = Stroke(width = 6.dp.toPx())
)
}
}
Output:

There is another overload of drawRect() that accepts brush instead of color. It is used to create gradient effects.
@Composable
fun MyUI() {
Canvas(
modifier = Modifier
.size(size = 300.dp)
.border(width = 2.dp, color = Color.Magenta)
) {
drawRect(
brush = Brush.horizontalGradient(listOf(Color.Magenta, Color.Yellow)),
size = Size(width = 160.dp.toPx(), height = 100.dp.toPx()),
topLeft = Offset(x = 70.dp.toPx(), y = 100.dp.toPx()),
style = Stroke(width = 6.dp.toPx())
)
}
}
Output:

This is all about drawRect() function. I hope you have learned how to draw a rectangle in Jetpack Compose Canvas. If you have any doubts, leave a comment below.
Related Articles: