How to Create Gradient Backgrounds in Jetpack Compose?

Jetpack Compose Gradient

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:

  1. horizontalGradient()
  2. verticalGradient()
  3. linearGradient()
  4. radialGradient()
  5. sweepGradient()

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:

Horizontal Gradient Example

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:

Start and End Positions

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:

Dp to Px

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:

Color Stops Gradient

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:

Vertical

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:

Linear Gradient

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:

radial

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:

Sweep Gradient

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:

Leave a Comment