W Jetpack Compose Glimmer komponent surface jest podstawowym elementem składowym, który reprezentuje odrębny obszar wizualny lub fizyczną granicę dla komponentów, takich jak przyciski i karty.
Powierzchnia odpowiada za te właściwości wizualne i fizyczne:
- Przycinanie: przycina elementy podrzędne do określonego kształtu.
- Obramowanie: rysuje wewnętrzne obramowanie, aby podkreślić granicę komponentu. Gdy jest wybrany, rysuje szersze obramowanie z wyróżnieniem.
- Tło: stosuje kolor tła do obszaru powierzchni.
- Efekty głębi: renderuje cienie
DepthEffectna podstawie stanu komponentu (np. domyślnego lub wybranego). - Kolor treści: określa kolor tekstu i ikon wewnątrz powierzchni, który domyślnie jest obliczany na podstawie koloru tła.
- Stany interakcji: rysuje nakładkę po naciśnięciu powierzchni oraz szersze obramowanie z wyróżnieniem, gdy jest wybrana.
Przykład: tworzenie powierzchni
Poniższy kod tworzy powierzchnię z przycinaniem, tłem i domyślnymi obramowaniami:
@Composable
fun SurfaceSample() {
Box(Modifier.surface().padding(horizontal = 24.dp, vertical = 20.dp)) {
Text("This is a surface")
}
}
Interakcja i wybór
Powierzchnie domyślnie nie są wybieralne, więc użytkownicy nie mogą z nimi wchodzić w interakcje. W większości przypadków powierzchnie powinny być interaktywne, aby użytkownicy mogli konsekwentnie przenosić fokus i poruszać się między komponentami. W przypadku powierzchni, które mają być tylko wybieralne, możesz użyć modyfikatora Compose focusable. Podobnie możesz utworzyć powierzchnię, którą można
kliknąć, używając modyfikatora clickable Compose. W przypadku powierzchni, które wymagają działań, możesz też użyć innych modyfikatorów.
Poniższy kod zawiera przykłady powierzchni, które można wybrać i kliknąć:
@Composable fun FocusableSurfaceSample() { val interactionSource = remember { MutableInteractionSource() } Box( modifier = Modifier .size(100.dp) .surface(interactionSource = interactionSource) .focusable(interactionSource = interactionSource), contentAlignment = Alignment.Center ) { Text("Focusable") } } @Composable fun ClickableSurfaceSample() { val interactionSource = remember { MutableInteractionSource() } Box( modifier = Modifier .size(100.dp) .surface(interactionSource = interactionSource) .focusable(interactionSource = interactionSource) .clickable( interactionSource = interactionSource, indication = null ) { /* Handle click action */ }, contentAlignment = Alignment.Center ) { Text("Clickable") } }
Najważniejsze informacje o kodzie
Wspólne źródło interakcji w przypadku powierzchni, które można wybrać: zarówno
.surface()i.focusable()muszą mieć to samointeractionSource. Dzięki temu powierzchnia może reagować na zmiany wyboru.Wspólne źródło interakcji w przypadku powierzchni, które można kliknąć: zarówno
.surface(), jak i.clickable()muszą mieć to samointeractionSource. Dzięki temu stany wizualne (np. naciśnięcie lub wybór) są zsynchronizowane, co pozwala powierzchni reagować wizualnie na dane wejściowe użytkownika.Kolejność modyfikatorów: kolejność modyfikatorów jest bardzo ważna. Ponieważ
.surface()przycina układ, umieszczenie go przed.clickable()zapewnia, że docelowy element dotykowy jest ograniczony do kształtu powierzchni. Jeśli.clickable()występuje jako pierwszy, obszar interakcji może wykraczać poza widoczne, przycięte granice komponentu.
SurfaceDepthEffect
Klasa SurfaceDepthEffect zarządza przejściem cieni między
stanami interakcji:
depthEffect: efekt cienia używany, gdy powierzchnia jest w stanie domyślnym.focusedDepthEffect: efekt cienia używany, gdy powierzchnia jest wybrana.