
In this article, we’ll learn how to create gradient backgrounds in Jetpack Compose using the built-in Brush API.
Prerequisites:
For this article, create an empty Jetpack Compose project and open the MainActivity file. Create a composable called MyUI() and call it from the onCreate() method.
// these are the imports we use in this article
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
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.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
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().
Jetpack Compose provides Brush class to create gradient effects. It is a sealed class with the following methods:
Let us look at them one by one.
Horizontal Gradients:
The horizontalGradient() creates a gradient effect from left to right. The colors are evenly distributed.
@Stable
fun horizontalGradient(
colors: List<Color>,
startX: Float = 0.0f,
endX: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush
It takes multiple parameters:
colors – List of colors. You should specify at least two.
startX – Starting x position of the gradient. Its default value is 0 which means left of the drawing area.
endX – Ending x position of the gradient. Its default value is Float.POSITIVE_INFINITY which indicates the right of the drawing area.
tileMode – It defines what happens at the edge of the gradient (see the docs).
Here is a simple example:
@Composable
fun MyUI() {
Box(
modifier = Modifier
.size(size = 300.dp)
.background(
brush = Brush.horizontalGradient(
colors = listOf(
Color.Cyan,
Color.Magenta
)
)
)
) {
}
}
Output:

Let’s change the starting and ending positions:
@Composable
fun MyUI() {
Box(
modifier = Modifier
.size(size = 300.dp)
.background(
brush = Brush.horizontalGradient(
colors = listOf(
Color.Cyan,
Color.Magenta
),
startX = 300f,
endX = 560f
)
)
) {
}
}
Output:

If you want set precise positions in dp, convert dp to pixels.
@Composable
fun MyUI() {
val pxStart = with(LocalDensity.current) { 100.dp.toPx() }
val pxEnd = with(LocalDensity.current) { 250.dp.toPx() }
Box(
modifier = Modifier
.size(size = 300.dp)
.background(
brush = Brush.horizontalGradient(
colors = listOf(
Color.Cyan,
Color.Magenta
),
startX = pxStart,
endX = pxEnd
)
)
) {
}
}
Output:

There is also another overload of the horizontalGradient() which accepts color stops:
@Stable
fun horizontalGradient(
vararg colorStops: Pair<Float, Color>,
startX: Float = 0.0f,
endX: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush
Example:
@Composable
fun MyUI() {
Box(
modifier = Modifier
.size(size = 300.dp)
.background(
brush = Brush.horizontalGradient(
0.0f to Color.Yellow,
0.5f to Color.Cyan,
1.0f to Color.Magenta,
startX = 0f,
endX = Float.POSITIVE_INFINITY
)
)
) {
}
}
Output:

The offset values represent the width of the box in terms of percentage.
0.0f represents 0% (left end of the box)
0.5f represents 50% (center of the box)
1.0f represents 100% (right end of the box)
From 0% to 50%, it creates a gradient with Yellow and Cyan. From 50% to 100%, it creates a gradient with Cyan and Magenta.
The remaining gradient functions are similar to the horizontalGradient. Let’s look at them.
Vertical Gradients:
The verticalGradient() creates a gradient effect from top to bottom.
with colors:
fun verticalGradient(
colors: List<Color>,
startY: Float = 0.0f,
endY: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush
with color stops:
fun verticalGradient(
vararg colorStops: Pair<Float, Color>,
startY: Float = 0.0f,
endY: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush
Example:
@Composable
fun MyUI() {
Box(
modifier = Modifier
.size(size = 300.dp)
.background(
brush = Brush.verticalGradient(
colors = listOf(Color.Green, Color.Yellow)
)
)
) {
}
}
Output:

Linear Gradients:
The linearGradient() is similar to the above gradients, but we can specify the start and end positions using the Offset function.
witch colors:
fun linearGradient(
colors: List<Color>,
start: Offset = Offset.Zero,
end: Offset = Offset.Infinite,
tileMode: TileMode = TileMode.Clamp
): Brush
with color stops:
fun linearGradient(
vararg colorStops: Pair<Float, Color>,
start: Offset = Offset.Zero,
end: Offset = Offset.Infinite,
tileMode: TileMode = TileMode.Clamp
): Brush
Example:
@Composable
fun MyUI() {
// convert the box size to pixels
val boxSize = with(LocalDensity.current) { 300.dp.toPx() }
Box(
modifier = Modifier
.size(size = 300.dp)
.background(
brush = Brush.linearGradient(
colors = listOf(Color.Green, Color.Yellow),
start = Offset(0f, 0f), // top left corner
end = Offset(boxSize, boxSize) // bottom right corner
)
)
) {
}
}
Output:

Radial Gradients:
The radialGradient() creates a gradient effect that starts from the middle and spreads outwards.
with colors:
fun radialGradient(
colors: List<Color>,
center: Offset = Offset.Unspecified,
radius: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush
with color stops:
fun radialGradient(
vararg colorStops: Pair<Float, Color>,
center: Offset = Offset.Unspecified,
radius: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush
Example:
@Composable
fun MyUI() {
// convert the box size to pixels
val boxSize = with(LocalDensity.current) { 300.dp.toPx() }
Box(
modifier = Modifier
.size(size = 300.dp)
.background(
brush = Brush.radialGradient(
colors = listOf(Color.Green, Color.Yellow),
center = Offset(x = boxSize / 2, y = boxSize / 2) // center
)
)
) {
}
}
Output:

Sweep Gradients:
sweepGradient() is similar to the conic gradient function in CSS. The sweep starts relative to 3 o’clock and ends at the same starting position.
with colors:
fun sweepGradient(
colors: List<Color>,
center: Offset = Offset.Unspecified
): Brush
with color stops:
fun sweepGradient(
vararg colorStops: Pair<Float, Color>,
center: Offset = Offset.Unspecified
): Brush
Example:
@Composable
fun MyUI() {
// convert the box size to pixels
val boxSize = with(LocalDensity.current) { 300.dp.toPx() }
Box(
modifier = Modifier
.size(size = 300.dp)
.background(
brush = Brush.sweepGradient(
colors = listOf(Color.Green, Color.Yellow),
center = Offset(x = boxSize / 2, y = boxSize / 2) // center
)
)
) {
}
}
Output:

Look at these beautiful loading dialog and button styles designed using these gradient functions.
This is all about creating gradient backgrounds in Jetpack Compose. I hope you have learned something new. If you have any doubts, comment below.
Related Articles: