Superfici in Jetpack Compose Glimmer

Dispositivi XR applicabili
Queste indicazioni ti aiutano a creare esperienze per questi tipi di dispositivi XR.
Display Glasses

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 DepthEffect in 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 same interactionSource. 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 stesso interactionSource. 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.