Skip to main content
Donovan LaDuke - Developer

Tiled Image Backgrounds in Jetpack Compose


Featured in Android Weekly Issue 602

In converting an existing app to use Compose, it is not uncommon to run into scenarios where a solution for converting legacy code to a Compose solution is not obvious. One such example is a drawable intended to be used with a repeated tileMode. In XML views, the drawable would be referenced in a bitmap and perhaps layered in a layer-list, neither of which are available in Compose. Enter ShaderBrush and ImageShader to accomplish the same task.

Repeated Image Background Example #

First, get access to the image resource.

val image = ImageBitmap.imageResource(
  R.drawable.img_my_background
)

Then, create a ShaderBrush from an ImageShader with the image and configure how to tile the image. This example uses TileMode.Repeated but be sure to check out the other modes in case they are a better fit for the given use case.

val imageBrush = remember(image) { 
  ShaderBrush(
    shader = ImageShader(
      image = image, 
      tileModeX = TileMode.Repeated, 
      tileModeY = TileMode.Repeated,
    )
  ) 
}

Finally, apply the image to the background using the background modifier.

Box(modifier = Modifier.background(brush = imageBrush))

The image can be applied as the background for any composable and can be made even more flexible by creating a reusable modifier like this.

fun Modifier.starBackground() {
  val image = ...
  val imageBrush = ...

  return this.background(brush = imageBrush)
} 

Box(modifier = Modifier.myImageBackground())

This example covers most scenarios, but if the image needs to be tinted, an additional step can be taken. In this case, instead of setting the background directly, use drawBehind in a canvas with the ShaderBrush.

fun Modifier.starBackground(color: Color) {
  val image = ...
  val imageBrush = ...

  this.drawBehind {
    drawRect(
      brush = imageBrush,
      colorFilter = ColorFilter.tint(color = color)
    )
  }
}

Box(modifier = Modifier.starBackground(Color.Blue))

Conclusion #

Now the background can be used wherever and be in any number of colors! This example is fairly simple, but more complex styling can be accomplished by adding multiple background modifiers or by adding additional draw calls in the drawBehind modifier. Check out this gist to see more and explore the code. Until next time, thanks!

Did you find this content helpful?

Please share this post and be sure to subscribe to the RSS feed to be notified of all future articles!

Want to go above and beyond? Help me out at one of the services below, it goes a long way in helping run this site. Thank you in advance!

Donate with PayPal Buy me a Coffee on Ko-fi Support me on Patreon