Implementa i gesti di pizzicamento per lo zoom per supportare i contenuti scalabili nella tua app. Questo è il metodo standard e coerente con la piattaforma per migliorare l'accessibilità, consentendo agli utenti di regolare in modo intuitivo le dimensioni del testo e degli elementi UI in base alle loro esigenze. La tua app può definire un comportamento di ridimensionamento personalizzato con un controllo granulare e un comportamento contestuale che offre un'esperienza che gli utenti spesso scoprono più rapidamente rispetto a una funzionalità a livello di sistema come l'ingrandimento dello schermo.
Scegli una strategia di scalabilità
Le strategie descritte in questa guida fanno sì che la UI venga ridisposta e riorganizzata per adattarsi alla larghezza dello schermo. Ciò offre un vantaggio significativo in termini di accessibilità, eliminando la necessità di eseguire la panoramica orizzontale e il frustrante movimento a "zig-zag" che altrimenti sarebbe necessario per leggere lunghe righe di testo.
Ulteriori letture: la ricerca conferma che per gli utenti con ipovisione, i contenuti con ridisposizione sono molto più leggibili e facili da navigare rispetto alle interfacce che richiedono la panoramica bidimensionale. Per maggiori dettagli, consulta A Comparison of Pan-and-Scan and Reflowable Content on Mobile Devices.
Scala tutti gli elementi o solo gli elementi di testo
La tabella seguente mostra l'effetto visivo di ogni strategia di scalabilità.
| Strategia | Scalabilità della densità | Ridimensionamento carattere |
|---|---|---|
Comportamento |
Scala tutti gli elementi in modo proporzionale. I contenuti vengono ridisposti per adattarsi al contenitore, in modo che l'utente non debba spostarsi orizzontalmente per visualizzarli tutti. |
Interessa solo gli elementi di testo. Il layout generale e i componenti non di testo rimangono delle stesse dimensioni. |
Cosa scala |
Tutti gli elementi visivi: testo, componenti (pulsanti, icone), immagini e spaziatura del layout (spaziatura interna, margini) |
Solo testo |
Dimostrazione |
Consigli
Ora che hai visto le differenze visive, la seguente tabella ti aiuta a valutare i compromessi e a scegliere la strategia migliore per i tuoi contenuti.
Tipo di UI |
Strategia consigliata |
Ragionamento |
Layout con molto testo Esempi: articoli, app di messaggistica |
Densità o ridimensionamento dei caratteri |
La scalabilità della densità è preferibile per ridimensionare l'intera area dei contenuti, incluse le immagini incorporate. La scalabilità dei caratteri è un'alternativa semplice se è necessario ridimensionare solo il testo. |
Layout strutturati visivamente Esempi: store, feed di social media |
Scalabilità della densità |
Conserva le relazioni visive tra immagini e testo in caroselli o griglie. La natura dinamica evita la panoramica orizzontale, che entrerebbe in conflitto con gli elementi di scorrimento nidificati. |
Rileva i gesti di ridimensionamento in Jetpack Compose
Per supportare i contenuti scalabili dall'utente, devi prima rilevare i gesti multi-touch. In Jetpack Compose, puoi farlo utilizzando Modifier.transformable.
Il modificatore transformable è un'API di alto livello che fornisce il delta zoomChange dall'ultimo evento di gesto. In questo modo, la logica di aggiornamento dello stato viene semplificata in un'accumulazione diretta (ad esempio, scale *= zoomChange), il che la rende ideale per le strategie di scalabilità adattiva trattate in questa guida.
Esempi di implementazioni
I seguenti esempi mostrano come implementare le strategie di scalabilità della densità e dei caratteri.
Scalabilità della densità
Questo approccio scala la base density di un'area della UI. Di conseguenza, tutte le misurazioni basate sul layout, tra cui spaziatura interna, spaziatura e dimensioni dei componenti, vengono ridimensionate, come se le dimensioni o la risoluzione dello schermo fossero cambiate. Poiché le dimensioni del testo dipendono anche dalla densità, anche queste vengono ridimensionate in modo proporzionale. Questa strategia è efficace quando vuoi ingrandire in modo uniforme tutti gli elementi all'interno di un'area specifica, mantenendo il ritmo visivo e le proporzioni complessive della UI.
private class DensityScalingState( // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x. private val minScale: Float = 0.75f, private val maxScale: Float = 3.5f, private val currentDensity: Density ) { val transformableState = TransformableState { zoomChange, _, _ -> scaleFactor.floatValue = (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale) } val scaleFactor = mutableFloatStateOf(1f) fun scaledDensity(): Density { return Density( currentDensity.density * scaleFactor.floatValue, currentDensity.fontScale ) } } @Composable fun DensityScalingSample() { val currentDensity = LocalDensity.current val scaleState = remember(currentDensity) { DensityScalingState(currentDensity = currentDensity) } Box( modifier = Modifier .fillMaxSize() .transformable(state = scaleState.transformableState), contentAlignment = Alignment.TopCenter ) { CompositionLocalProvider( LocalDensity provides scaleState.scaledDensity() ) { DemoCard() } } }
Ridimensionamento carattere
Questa strategia è più mirata e modifica solo il fattore fontScale. Il risultato è che solo gli elementi di testo aumentano o diminuiscono di dimensioni, mentre tutti gli altri componenti del layout, come contenitori, spaziatura interna e icone, rimangono di dimensioni fisse. Questa strategia è adatta per migliorare la leggibilità del testo nelle app con un'alta intensità di lettura.
class FontScaleState( // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x. private val minScale: Float = 0.75f, private val maxScale: Float = 3.5f, private val currentDensity: Density ) { val transformableState = TransformableState { zoomChange, _, _ -> scaleFactor.floatValue = (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale) } val scaleFactor = mutableFloatStateOf(1f) fun scaledFont(): Density { return Density( currentDensity.density, currentDensity.fontScale * scaleFactor.floatValue ) } } @Composable fun FontScalingSample() { val currentDensity = LocalDensity.current val scaleState = remember { FontScaleState(currentDensity = currentDensity) } Box( modifier = Modifier .fillMaxSize() .transformable(state = scaleState.transformableState), contentAlignment = Alignment.TopCenter ) { CompositionLocalProvider( LocalDensity provides scaleState.scaledFont() ) { DemoCard() } } }
UI della demo condivisa
Questo è il composable DemoCard condiviso utilizzato da entrambi gli esempi precedenti per evidenziare i diversi comportamenti di scalabilità.
@Composable private fun DemoCard() { Card( modifier = Modifier .width(360.dp) .padding(16.dp), shape = RoundedCornerShape(12.dp) ) { Column( modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { Text("Demo Card", style = MaterialTheme.typography.headlineMedium) var isChecked by remember { mutableStateOf(true) } Row(verticalAlignment = Alignment.CenterVertically) { Text("Demo Switch", Modifier.weight(1f), style = MaterialTheme.typography.bodyLarge) Switch(checked = isChecked, onCheckedChange = { isChecked = it }) } Row(verticalAlignment = Alignment.CenterVertically) { Icon(Icons.Filled.Person, "Icon", Modifier.size(32.dp)) Spacer(Modifier.width(8.dp)) Text("Demo Icon", style = MaterialTheme.typography.bodyLarge) } Row( Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { Box( Modifier .width(100.dp) .weight(1f) .height(80.dp) .background(Color.Blue) ) Box( Modifier .width(100.dp) .weight(1f) .height(80.dp) .background(Color.Red) ) } Text( "Demo Text: Lorem ipsum dolor sit amet, consectetur adipiscing elit," + " sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", style = MaterialTheme.typography.bodyMedium, textAlign = TextAlign.Justify ) } } }
Suggerimenti e considerazioni
Per creare un'esperienza più rifinita e accessibile, tieni presente i seguenti suggerimenti:
- Valuta la possibilità di offrire controlli di ridimensionamento non basati su gesti: alcuni utenti potrebbero avere difficoltà con i gesti. Per supportare questi utenti, valuta la possibilità di fornire un modo alternativo per regolare o reimpostare la scala che non si basi sui gesti.
- Crea per tutte le scale: testa la tua UI sia con la scalabilità in-app sia con le impostazioni di visualizzazione o dei caratteri a livello di sistema. Verifica che i layout dell'app si adattino correttamente senza interrompere, sovrapporre o nascondere i contenuti. Scopri di più su come creare layout adattivi.