In Jetpack Compose Glimmer, il componente surface è un componente di base che rappresenta un'area visiva distinta o un confine fisico per componenti come pulsanti e schede.
Una superficie è responsabile delle seguenti proprietà visive e fisiche:
- Ritaglio: ritaglia i relativi elementi secondari in base a una forma specificata.
- Bordo: disegna un bordo interno per evidenziare il limite del componente. Quando è selezionato, disegna un bordo più ampio con un'evidenziazione.
- Sfondo: applica un colore di sfondo all'area della superficie.
- Effetti di profondità: esegue il rendering delle ombre
DepthEffectin base allo stato del componente (ad esempio predefinito rispetto a attivo). - Colore dei contenuti: fornisce un colore per il testo e le icone all'interno della superficie, calcolato per impostazione predefinita dal colore di sfondo.
- Stati di interazione: disegna una sovrapposizione premuta quando la superficie viene premuta e un bordo più ampio con un'evidenziazione quando è selezionato.
Esempio: creare una superficie
Il seguente codice crea una superficie con ritaglio, uno sfondo e bordi predefiniti:
@Composable fun SurfaceSample() { Box(Modifier.surface().padding(horizontal = 24.dp, vertical = 20.dp)) { Text("This is a surface") } }
Interaction and Focus
Surfaces aren't focusable by default, so users can't interact with them. In most
cases, surfaces should be interactive to let users consistently move focus and
navigate between components. You can use the Compose focusable modifer
for surfaces that are only intended to be focusable, or the Compose
clickable modifer and other modifiers for surfaces that require actions.
You can create a focusable surface by combining a surface modifier with the
focusable modifier:
@Composable fun FocusableSurfaceSample() { val interactionSource = remember { MutableInteractionSource() } Box( Modifier.surface( // Provide the same interaction source here and to focusable to make sure that // surface appears focused when interacted with. interactionSource = interactionSource ) .focusable(interactionSource = interactionSource) .padding(horizontal = 24.dp, vertical = 20.dp) ) { Text("This is a focusable surface") } }
Key points about the code
- Shared interaction source: Both .
surface()and .focusable()must share the sameinteractionSource. This lets the surface react to focus changes.
Similarly, you can create a clickable surface:
@Composable fun ClickableSurfaceSample() { val interactionSource = remember { MutableInteractionSource() } Box( Modifier.surface( // Provide the same interaction source here and to clickable to make sure that // surface appears focused and pressed when interacted with interactionSource = interactionSource ) .clickable(interactionSource = interactionSource, onClick = {}) .padding(horizontal = 24.dp, vertical = 20.dp) ) { Text("This is a clickable surface") } }
Punti chiave sul codice
Fonte di interazione condivisa: entrambi .
surface()e .clickable()devono condividere lo stessointeractionSource. In questo modo, gli stati visivi (ad esempio pressione o messa a fuoco) vengono sincronizzati, consentendo alla superficie di reagire visivamente all'input dell'utente.Ordine dei modificatori: la sequenza dei modificatori è fondamentale. Perché .
surface()taglia un layout, posizionandolo prima .clickable()garantisce che il touch target sia vincolato alla forma della superficie. Se .clickable()viene prima, l'area di interazione potrebbe estendersi oltre i limiti visibili e ritagliati del componente.
SurfaceDepthEffect
La classe SurfaceDepthEffect gestisce la transizione delle ombre tra gli stati di interazione:
depthEffect: l'effetto ombra utilizzato quando la superficie è nel suo stato predefinito.focusedDepthEffect: l'effetto ombra utilizzato quando la superficie è messa a fuoco.