
Náš Android tech stack pro vývoj mobilních aplikací

28. Feb 2023
AndroidSnackbar je součást uživatelského rozhraní, která poskytuje krátké zprávy ve spodní části obrazovky. Slouží k informování uživatelů o tom, že aplikace provedla nebo provede nějakou akci. V jednom okamžiku lze použít pouze jeden snackbar a musí obsahovat pouze jednu akci, která je volitelná.
Tato jednoduchá komponenta se skládá ze zprávy (1), kontejneru (2) a volitelného akčního tlačítka (3). Zpráva může mít maximálně 2 řádky.
V Jetpack Compose je composable funkce s názvem Snackbar. Je to jen vizuální reprezentace snackbaru definovaného v pokynech Material designu, bez možnosti zobrazit nebo skrýt a bez animací. Obvykle je třeba použít SnackbarHost.
Tato komponenta je zodpovědná za zobrazování snackbaru (nebo jeho skrytí po definované době) a za jeho animace. Jednoduše řečeno, SnackbarHost je wrapper výše uvedeného Snackbaru. K tomu jsou zapotřebí 3 parametry:
@Composable
fun SnackbarHost(
hostState: SnackbarHostState,
modifier: Modifier = Modifier,
snackbar: @Composable (SnackbarData) -> Unit = { Snackbar(it) }
)
Jak napovídá popisný název třídy, slouží k ovládání stavu SnackbarHost. Podle pokynů Material designu by měl být v daném okamžiku zobrazen pouze jeden snackbar, ostatní jsou v pořadí a budou zobrazeny později pomocí SnackbarHostState.
Jediným povinným parametrem SnackbarHostState je hostState, který lze snadno získat pomocí konstruktoru. Pak můžete SnackbarHost jednoduše umístit kamkoli chcete. Snackbar se ale stále nezobrazuje, tak jak to mám udělat?
val snackbarHostState = remember { SnackbarHostState() }
.
.
.
SnackbarHost(hostState = snackbarHostState)
Snackbar se zobrazí jako reakce na něco, v našem případě je tím „něčím“ kliknutí na tlačítko. ShowSnackbar je suspend funkce, takže je zapotřebí coroutine scope. Coroutine scope programu si musíte zapamatovat mimo funkce onClick, protože po zrušení rozsahu se snackbar odstraní z fronty.
@Composable
fun SnackbarScreen() {
val scope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
.
.
.
FloatingActionButton(
onClick = {
//Important part here
scope.launch {
snackbarHostState.showSnackbar("Hello there")
}
//
},
content = { Icon(imageVector = Icons.Default.Add, contentDescription = "") }
)
SnackbarHost(hostState = snackbarHostState)
}
Tady je důležité upravit parametr SnackbarHost. Bez našich úprav se použije předvolený Snackbar composable. Pomocí níže uvedeného kódu se použije náš design snackbaru, ale předvolené chování snackbaru bude zachováno.
SnackbarHost(
modifier = Modifier.align(Alignment.BottomCenter),
hostState = snackbarHostState,
snackbar = { snackbarData: SnackbarData ->
Card(
shape = RoundedCornerShape(8.dp),
border = BorderStroke(2.dp, Color.White),
modifier = Modifier
.padding(16.dp)
.wrapContentSize()
) {
Column(
modifier = Modifier.padding(8.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(imageVector = Icons.Default.Notifications, contentDescription = "")
Text(text = snackbarData.message)
}
}
}
)