28. Feb 2023
AndroidJetpack Compose Basics – Jak používat a vytvořit vlastní CompositionLocal
V dnešnej epizóde série Jetpack Compose Basics vám ukážem, ako použiť CompositionLocal na implicitné odovzdávanie údajov cez kompozíciu, vďaka čomu bude zoznam parametrov funkcie prehľadnejší.
Co je CompositionLocal v Jetpack Compose?
Jak můžete předat data prostřednictvím kompozice? Jednou z cest je poslat je, jako parametry do každého composable, ale v případě barev nebo typografie může být situace dost chaotická, protože je potřebujete téměř v každém composable.
Druhou možností je použít CompositionLocal. Je to nástroj pro implicitní odevzdávání údajů s kompozicí, např. MaterialTheme využívá CompositionLocal k poskytování barev, tvarů a typografie kdekoli.
Jak používat CompositionLocal v Jetpack Compose?
Podívejte se na příklad kódu níže. Barva textů se v Text composable nemění přímo, ale používá se provider LocalContentColor. Tato technika se v rámci Jetpack Compose používá velmi hojně a může být užitečná, pokud potřebujete změnit atribut všech položek composables ve scope. Aktuální hodnota CompositionLocal odpovídá nejbližší hodnotě poskytnuté předkem ve specifikované části kompozice.
CompositionLocalProvider(LocalContentColor provides Color.Blue) {
// content color for all components in this scope is blue
Text(text = "Lorem")
CompositionLocalProvider(LocalContentColor provides Color.Red) {
// content color for all components in this scope is blue
Text(text = "ipsum")
Text(text = "dolor")
CompositionLocalProvider(LocalContentAlpha provides 0.2f) {
// alpha of all components in this scope is 0.2f
Text(text = "sit...")
}
}
}
Pokud vaše otázka zní: Jak může Text composable vědět, jakou barvu nebo alfu použít? – odpověď je v implementaci Text composable. Barva textu se určí pomocí LocalContentColor.current, pokud caller nespecifikuje atribut color.
val textColor = color.takeOrElse {
style.color.takeOrElse {
LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
}
}
Jak vytvořit vlastní CompositionLocal?
Zaprvé, CompositionLocal skutečně dává smysl, zejména pokud ho může potenciálně použít jakýkoli potomek, nejen několik z nich. Raději si dvakrát rozmyslete, zda ho chcete opravdu vytvořit, nebo zda chcete použít explicitní parametry. Ne vždy je to nejlepší řešení a nedoporučuje se to přehánět. Nevýhodou je, že je těžší zajistit, aby byla hodnota každého CompositionLocal splněna, pokud vznikají implicitní závislosti.
Za druhé, v CompositionLocal by měla být vždy nějaká hodnota, přičemž při vytváření by měla být poskytnuta vaše předvolená hodnota.
Existují 2 možnosti vytvoření CompositionLocal
- compositionLocalOf – změna hodnoty znehodnotí pouze obsah, který čte jeho aktuální hodnotu
- staticCompositionLocalOf – čtení nesleduje Compose. Změna hodnoty způsobí, že se překomponuje celý obsah lambda, nejen místa, kde se načítá aktuální hodnota.
// Definition with default value
val LocalPaddings = compositionLocalOf { PaddingValues(0.dp) }
.
.
.
// Using CompositionLocal App-wide
CompositionLocalProvider(LocalPaddings provides PaddingValues(24.dp)) {
/*
your app composables...
*/
}
Čtení z vytvořených LocalPaddings může vypadat takto. Box v níže uvedeném příkladu má teď paddings pro celou aplikaci – PaddingValues (24 dp).
Box(
modifier = Modifier.padding(LocalPaddings.current)
){
// some composable padded by 24.dp
}
Další články ze série Jetpack Compose Basics:
- Vyzkoušejte Scaffold a sestavte několik materiálových komponent se správným rozložením!
- Naučte se správně používat Snackbar
- Jak načítat obrázky z Bitmapy, Vectoru, Painteru nebo URL pomocí funkce Coil
- Jak používat text field composables v zájmu splnění specifikace Material designu
- Jak používat Backdrop Scaffold composable
- Hledáte alternativu k menu nebo dialogům? Vyzkoušejte Modal Bottom Sheet