Jetpack Compose Basics - How to use and create own CompositionLocal
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.
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:
- Learn how to use Snackbar properly
- Try Scaffold an put together several material components with the right layout!
- How to load images from Bitmap, Vector, Painter or from URL with Coil
- How to use text field composables to meet the Material design specification
- How to use Backdrop Scaffold composable
- Looking for an alternative to menus or dialogues? Try the Modal Bottom Sheet