28. Feb 2023
AndroidJetpack Compose Basics – Vyzkoušejte Scaffold a sestavte několik materiálových komponent se správným rozložením!
Jetpack Compose je možná budoucností programování pro Android. Většina z jeho funkcí a composables je snadno použitelná a opravdu srozumitelná, jiné mohou mít obrovské množství atributů. V základech Jetpack Compose budou některé z nich vysvětleny, Scaffold jako první.
Scaffold je základní composable funkce používaná v Material aplikacích. Tato komponenta umožňuje snadno sestavit několik „materiálových“ komponent pro vytvoření obrazovky aplikace se zajištěním správného rozložení (např. správnou polohou snackbaru v horní části plovoucího akčního tlačítka, animace, stav draweru a další).
Scaffold obsahuje sloty pro TopBar, BottomBar, Snackbar, FloatingActionButton a Drawer. Přizpůsobení vyžaduje řadu parametrů, ale nebojte se, většina z nich je celkem zřejmá a vyžaduje jen jednoduché vysvětlení.
@Composable
fun Scaffold(
modifier: Modifier = Modifier,
scaffoldState: ScaffoldState = rememberScaffoldState(),
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
isFloatingActionButtonDocked: Boolean = false,
drawerContent: @Composable (ColumnScope.() -> Unit)? = null,
drawerGesturesEnabled: Boolean = true,
drawerShape: Shape = MaterialTheme.shapes.large,
drawerElevation: Dp = DrawerDefaults.Elevation,
drawerBackgroundColor: Color = MaterialTheme.colors.surface,
drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
drawerScrimColor: Color = DrawerDefaults.scrimColor,
backgroundColor: Color = MaterialTheme.colors.background,
contentColor: Color = contentColorFor(backgroundColor),
content: @Composable (PaddingValues) -> Unit
)
- modifier – volitelný parametr sloužící k úpravě vlastností Scaffoldu zvenčí
- scaffoldState – zapamatovaný stav obrazovky. ScaffoldState obsahuje informace o draweru (ať už otevřeném, nebo zavřeném) a snackbarHost (zda se zobrazuje snackbar). Pokud nepotřebujete se stavem komunikovat (např. showing snackbar nebo opening drawer), nechte ho tak, jak je.
- floatingActionButtonPosition – pozice floating akčního tlačítka, možné hodnoty jsou Center, nebo End
- isFloatingActionButtonDocked – parametr boolean, jestli se má plovoucí akční tlačítko překrývat se spodní lištou o poloviny své výšky. Tento parametr je ignorován, pokud není použitý žádný dolní bar.
- drawerGestureEnabled – zda je možné s drawerem interagovat pomocí gest
- drawerShape – tvar draweru
- drawerElevation – pozice draweru
- drawerBackgroundColor – barva pozadí, která se použije pro drawer
- drawerContentColor – barva obsahu, který se použije uvnitř draweru
- drawerScrimColor – barva scrimu, který zakrývá obsah, pokud je drawer otevřený
- backgroundColor – barva pozadí těla Scaffoldu, ve většině případů ponecháte tento parametr na předvolené hodnotě
- contentColor – barva obsahu v těle Scaffoldu, ve většině případů ponecháte tento parametr na předvolené hodnotě
Teď je čas probrat netriviální, ale přesto relativně jednoduché parametry.
TopBar
topBar: @Composable () -> Unit = {}
Volitelný parametr. Jak vidíte v definici, měli byste poskytnout composable funkci, která vyplní slot v horní části obrazovky. Můžete použít buď předdefinovaný composable TopAppBar, nebo vlastní implementaci na přizpůsobení vlastních návrhů. Předvolená hodnota je prázdná lambda, v tomto případě se horní lišta nepoužívá. Tento úryvek kódu implementuje program TopAppBar odevzdaný parametru topBar.
topBar = {
TopAppBar(
title = { Text(text = "Title text") },
navigationIcon = {
Icon(modifier = padding, imageVector = Icons.Default.ArrowBack, contentDescription = "Back")
},
actions = {
Icon(modifier = padding, imageVector = Icons.Default.Favorite, contentDescription = "Favorite")
Icon(modifier = padding, imageVector = Icons.Default.Search, contentDescription = "Search")
}
)
}
BottomBar
bottomBar: @Composable () -> Unit = {}
Volitelný parametr. V takovém případě je zapotřebí composable funkce, která vyplní slot v dolní části obrazovky. Je možné použít předdefinované composables, jako je BottomAppBar nebo BottomNavigation, ale ty jsou ve skutečnosti jen doporučením. Můžete poskytnout vlastní composable funkci. Tento úryvek kódu implementuje BottomAppBar odevzdaný parametru bottomBar.
bottomBar = {
BottomAppBar(
content = {
Icon(modifier = padding, imageVector = Icons.Default.Menu, contentDescription = "Menu")
Icon(modifier = padding, imageVector = Icons.Default.Search, contentDescription = "Search")
Text(text = "Anything can be here")
}
)
}
FloatingActionButton
floatingActionButton: @Composable () -> Unit = {}
Volitelný parametr. Plovoucí akční tlačítko (FAB) představuje primární akci na obrazovce. Je možné ho nakonfigurovat i pomocí funkce floatingActionButtonPosition (Center nebo End) a isFloatingActionButtonDocked (boolean, pokud se má FAB překrývat s BottomBar). Preferovanou composable pro tento slot je FloatingActionButton, ale můžete použít jakoukoli composable funkci. Tento úryvek kódu implementuje FloatingActionButton odevzdaný parametru floatingActionButton.
floatingActionButton = {
FloatingActionButton(
onClick = {},
content = {
Icon(imageVector = Icons.Default.Favorite,contentDescription = "")
}
)
}
Drawer
drawerContent: @Composable (ColumnScope.() -> Unit)? = null
Volitelný parametr. Drawer představuje obsah, který lze tahat zleva (nebo pro RTL zprava). Drawer lze taky zobrazit pomocí funkce scaffoldState.drawerState.open() v coroutine scope. Lambda, která je tady zapotřebí, je již funkcí nad ColumnScope, takže každá composable, která bude v lambdě použitá, bude umístěná jako ve sloupci (shora dolů). O animace, pozadí scrim a přetažení prstem se stará Scaffold. Tento úryvek kódu implementuje 4 položky odevzdané do parametru drawerContent.
drawerContent = {
Icon(
modifier = Modifier.padding(16.dp),
imageVector = Icons.Default.Person,
contentDescription = ""
)
Text(modifier = Modifier.padding(16.dp), text = "First line")
Text(modifier = Modifier.padding(16.dp), text = "Second line")
Text(modifier = Modifier.padding(16.dp), text = "Third line")
}
SnackbarHost
snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) }
Snackbar je o něco složitější. Parametr SnackbarHost je možné použít, pokud chceme vlastní vzhled Snackbaru, jinak se použije předvolený design a chování implementované ve SnackbarHost. Můžeme to nechat na SnackbarHostu. Snackbary poskytují v dolní části obrazovky stručné zprávy o procesech aplikace. V našem ukázkovém úryvku se panel Snackbar zobrazí po kliknutí na položku FAB.
val scope = rememberCoroutineScope()
val scaffoldState = rememberScaffoldState()
.
.
.
scaffoldState = scaffoldState,
floatingActionButton = {
FloatingActionButton(
onClick = {
scope.launch {
scaffoldState.snackbarHostState.showSnackbar("Hello there!")
}
},
content = {
Icon(imageVector = Icons.Default.Favorite, contentDescription = "")
}
)
}
Pár věcí, které je třeba zmínit: showSnackbar (...) je suspend funkce, takže je potřeba coroutine scope. Závislý scope na kompozici můžeme získat jednoduše pomocí rememberCoroutineScope(). SnackbarHost zaručuje, že se v daném okamžiku zobrazí maximálně jeden snackbar, ostatní budou v pořadí.
Content
content: @Composable (PaddingValues) -> Unit
Zbývající část na obrazovce. Tady můžete použít libovolnou composable funkci. Lambda přijímá hodnoty PaddingValues, které by měly být aplikovány na root obsahu pomocí Modifier.padding, aby byly správně odsazeny horní a dolní bary.
Celý Scaffold se všemi widgety může vypadat takto.
Ď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
- Ako používať a vytvoriť vlastný CompositionLocal