11. Jan 2022
AndroidJetpack Compose Basics - Ako používať a vytvoriť 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ší.
Čo je CompositionLocal v Jetpack Compose?
Ako môžete odovzdať údaje prostredníctvom kompozície? Jedným zo spôsobov je poslať ich, ako parametre do každého composable, ale v prípade farieb alebo typografie môžu byť veci dosť chaotické, pretože ich potrebujete takmer v každom composable.
Druhou možnosťou je použiť CompositionLocal. Je to nástroj na implicitné odovzdávanie údajov kompozíciou. napr. MaterialTheme využíva CompositionLocal na poskytovanie farieb, tvarov a typografie kdekoľvek.
Ako používať CompositionLocal v Jetpack Compose?
Pozrite si príklad kódu nižšie. Farba textov sa v Text composable nemení priamo, ale používa sa provider LocalContentColor. Táto technika je široko používaná v rámci Jetpack Compose a môže byť užitočná, keď potrebujete zmeniť atribút všetkých composables položiek v scope. Aktuálna hodnota CompositionLocal zodpovedá najbližšej hodnote poskytnutej predkom v špecifikovanej časti kompozície.
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...")
}
}
}
Ak je vaša otázka - Ako môže Text composable vedieť, ktorú farbu alebo alfu použiť? - odpoveď je v implementácii Text composable. Farba textu sa určí pomocou LocalContentColor.current, pokiaľ caller nešpecifikuje atribút color.
val textColor = color.takeOrElse {
style.color.takeOrElse {
LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
}
}
Ako vytvoriť vlastný CompositionLocal?
Po prvé, CompositionLocal skutočne dáva zmysel, najmä ak ho môže potenciálne použiť ktorýkoľvek potomok, nie niekoľko z nich. Radšej si dvakrát rozmyslite, či ho naozaj chcete vytvoriť alebo len použiť explicitné parametre. Nie je to vždy najlepšie riešenie a neodporúča sa to preháňať. Nevýhodou je, že je ťažšie zabezpečiť, aby bola splnená hodnota každého CompositionLocal, keď vznikajú implicitné závislosti.
Po druhé, v CompositionLocal by mala byť vždy nejaká hodnota, pričom pri vytváraní by mala byť poskytnutá vaša predvolená hodnota.
Existujú 2 možnosti na vytvorenie CompositionLocal
- compositionLocalOf - zmena hodnoty znehodnotí iba obsah, ktorý číta jeho aktuálnu hodnotu
- staticCompositionLocalOf - čítanie nesleduje Compose. Zmena hodnoty spôsobí, že sa prekomponuje celý obsah lambda, nie len miesta, kde sa číta aktuálna hodnota
// Definition with default value
val LocalPaddings = compositionLocalOf { PaddingValues(0.dp) }
.
.
.
// Using CompositionLocal App-wide
CompositionLocalProvider(LocalPaddings provides PaddingValues(24.dp)) {
/*
your app composables...
*/
}
Čítanie z vytvorených LocalPaddings môže vyzerať takto. Box v príklade nižšie má teraz paddings pre celú aplikáciu - PaddingValues (24.dp).
Box(
modifier = Modifier.padding(LocalPaddings.current)
){
// some composable padded by 24.dp
}
Ďalšie články zo série Jetpack Compose Basics:
- Vyskúšaj Scaffold a zostav niekoľko materiálových komponentov so správnym rozložením!
- Nauč sa používať Snackbar správne
- Ako načítať obrázky z Bitmapy, Vectoru, Painteru alebo z URL pomocou funkcie Coil
- Ako používať text field composables pre splnenie Material design špecifikácie
- Ako používať Backdrop Scaffold composable
- Hľadáš alternatívu k menu alebo dialógom? Skús Modal Bottom Sheet