Jetpack Compose Basics - How to use and create own CompositionLocal
Mobile
2
 min read
February 23, 2022

Jetpack Compose Basics - How to use and create own CompositionLocal

Peter Šuly
Peter Šuly
Android developer
LinkedIn Logo

In today's episode of the Jetpack Compose basics series, I'll show you how to use CompositionLocal to implicitly pass data via composition, which will make function parameters clearer.

What is CompositionLocal in Jetpack Compose?

How can you pass data down through composition? One way is to send them as function parameters to each composable explicitly, but in case of let's say colors or typography things can get pretty messy because you need them in almost every composable.

Your second option is to use CompositionLocal. It's tool for passing data through composition implicitly. E.g. MaterialTheme uses CompositionLocal under the hood to provide colors, shapes and typography anywhere.

How to use CompositionLocal in Jetpack Compose?

Take a look at example code below. Color of texts is not changed directly in Text composable but LocalContentColor provider is used. This technique is widely used in Jetpack Compose framework and can be useful when you need to change attribute of all composables in scope. Current value of CompositionLocal corresponds to the closest value provided by ancestor in specified part of composition.

Example of using LocalContentColor
Example of using LocalContentColor

If your question is - How can Text composable know which color or alpha to use? - answer is in implementation of Text composable. Color of Text composable is resolved by LocalContentColor.current call unless caller doesn't specify the color attribute.

How to create own CompositionLocal?

Firstly, CompositionLocal really makes sense especially when it can be potentially used by any descendant not by few of them. You should better think twice about whether you really want to create it or just use exmplicit parameters. It is not always the best solution and is not recommended to overuse it. Downside is that it's harder to make sure a value for every CompositionLocal is satisfied when dependencies are implicit.

Secondly, there should always be some value in CompositionLocal, while creation you default value should be provided.

There are 2 option to create Composition Local

  • compositionLocalOf - change of value invalidates only the content that reads its current value
  • staticCompositionLocalOf - reads are not tracked by Compose. Change of value causes entire content lambda to be recomposed, instead of just places where current value is read

Reading from created LocalPaddings can look like this. Box in example below now have app wide paddings - PaddingValues(24.dp).

More articles from the Jetpack Compose Basics series:

Like what you see?
Join our newsletter.

Great! Welcome to newsletter.
Oops! Something went wrong while submitting your email.
High quality content once a month. No spam, we promise.
Your personal data is processed in accordance with our Memorandum on Personal Data Protection.

Páči sa vám náš content?
Odoberajte newsletter.

Great! Welcome to newsletter.
Oops! Something went wrong while submitting your email.
Vaše osobné údaje sú spracované v súlade s našim Memorandom na ochranu osobných údajov.