Last active
March 19, 2026 07:51
-
-
Save StefMa/a9d27ab56e19e4ab4bc1a505d4c46a62 to your computer and use it in GitHub Desktop.
CompositionLocal in Jetpack Compose
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class MainActivity : ComponentActivity() { | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| enableEdgeToEdge() | |
| setContent { | |
| MaterialTheme { | |
| Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> | |
| var analyticsProvider by remember { mutableStateOf<Analytics.Provider>(Analytics.Provider.Firebase) } | |
| CompositionLocalProvider(LocalAnalytics provides Analytics(analyticsProvider)) { | |
| Greeting(modifier = Modifier.padding(innerPadding)) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| @Composable | |
| fun Greeting(modifier: Modifier = Modifier) { | |
| val analytics = LocalAnalytics.current | |
| analytics.trackEvent("Greeting (Re)composed") | |
| Text( | |
| modifier = modifier, | |
| text = "Hello World!" | |
| ) | |
| } | |
| data class Analytics(private val provider: Provider) { | |
| sealed interface Provider { | |
| object LogCat : Provider | |
| object Println : Provider | |
| object Firebase : Provider | |
| } | |
| fun trackEvent(eventName: String) { | |
| when (provider) { | |
| Provider.LogCat -> println("Debug: LogCat - Tracking event: $eventName") | |
| Provider.Println -> println("Debug: Println - Tracking event: $eventName") | |
| Provider.Firebase -> println("Debug: Firebase - Tracking event: $eventName") | |
| } | |
| } | |
| } | |
| val LocalAnalytics = compositionLocalOf { Analytics(Analytics.Provider.Println) } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class MainActivity : ComponentActivity() { | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| enableEdgeToEdge() | |
| setContent { | |
| MaterialTheme { | |
| Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> | |
| var analyticsProvider by remember { mutableStateOf<Analytics.Provider>(Analytics.Provider.Firebase) } | |
| CompositionLocalProvider( | |
| LocalAnalytics provides Analytics(analyticsProvider, "main") | |
| ) { | |
| Column(Modifier.padding(innerPadding)) { | |
| RadioButton( | |
| text = "Println", | |
| selected = analyticsProvider is Analytics.Provider.Println, | |
| onClick = { analyticsProvider = Analytics.Provider.Println } | |
| ) | |
| RadioButton( | |
| text = "LogCat", | |
| selected = analyticsProvider is Analytics.Provider.LogCat, | |
| onClick = { analyticsProvider = Analytics.Provider.LogCat } | |
| ) | |
| RadioButton( | |
| text = "Firebase", | |
| selected = analyticsProvider is Analytics.Provider.Firebase, | |
| onClick = { analyticsProvider = Analytics.Provider.Firebase } | |
| ) | |
| TrackableButton("0. View") | |
| Column { | |
| CompositionLocalProvider( | |
| LocalAnalytics provides | |
| LocalAnalytics.current.wrapWithPrefix("view1") | |
| ) { | |
| TrackableButton("1. View") | |
| Column { | |
| CompositionLocalProvider( | |
| LocalAnalytics provides | |
| LocalAnalytics.current.wrapWithPrefix("view2") | |
| ) { | |
| TrackableButton("2. View") | |
| Column { | |
| CompositionLocalProvider( | |
| LocalAnalytics provides | |
| LocalAnalytics.current.wrapWithPrefix("view3") | |
| ) { | |
| TrackableButton("3. View") | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| @Composable | |
| fun RadioButton( | |
| text: String, | |
| selected: Boolean, | |
| onClick: () -> Unit, | |
| ) { | |
| Row { | |
| androidx.compose.material3.RadioButton( | |
| selected = selected, | |
| onClick = onClick | |
| ) | |
| Text( | |
| text = text, | |
| modifier = Modifier | |
| .padding(start = 8.dp) | |
| .align(Alignment.CenterVertically) | |
| ) | |
| } | |
| } | |
| @Composable | |
| fun TrackableButton(text: String) { | |
| val analytics = LocalAnalytics.current | |
| val context = LocalContext.current | |
| analytics.trackEvent("TrackableButton (Re)composed") | |
| Button( | |
| onClick = { | |
| analytics.trackEvent("buttonClicked") | |
| Toast.makeText(context, "Button at $text clicked", Toast.LENGTH_SHORT).show() | |
| }, | |
| content = { Text(text) } | |
| ) | |
| } | |
| data class Analytics(private val provider: Provider, private val eventNamePrefix: String) { | |
| sealed interface Provider { | |
| object LogCat : Provider | |
| object Println : Provider | |
| object Firebase : Provider | |
| } | |
| fun trackEvent(eventName: String) { | |
| when (provider) { | |
| Provider.LogCat -> println("Debug: LogCat - Tracking event: ${eventNamePrefix + "_" + eventName}") | |
| Provider.Println -> println("Debug: Println - Tracking event: ${eventNamePrefix + "_" + eventName}") | |
| Provider.Firebase -> println("Debug: Firebase - Tracking event: ${eventNamePrefix + "_" + eventName}") | |
| } | |
| } | |
| fun wrapWithPrefix(appendPrefix: String): Analytics = | |
| copy(eventNamePrefix = eventNamePrefix + "_" + appendPrefix) | |
| } | |
| val LocalAnalytics = compositionLocalOf { Analytics(Analytics.Provider.Println, "null") } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment