Unterstützung von nutzerseitig skalierbaren Inhalten

Implementieren Sie Pinch-to-Zoom-Gesten, um skalierbare Inhalte in Ihrer App zu unterstützen. Dies ist die standardmäßige, plattformübergreifende Methode zur Verbesserung der Barrierefreiheit, mit der Nutzer die Größe von Text und UI-Elementen intuitiv an ihre Bedürfnisse anpassen können. Ihre App kann benutzerdefiniertes Skalierungsverhalten mit detaillierter Steuerung und kontextbezogenem Verhalten definieren, das Nutzern oft schneller auffällt als eine Funktion auf Systemebene wie die Bildschirmvergrößerung.

Skalierungsstrategie auswählen

Die in diesem Leitfaden behandelten Strategien führen dazu, dass die Benutzeroberfläche neu angeordnet wird, um der Bildschirmbreite zu entsprechen. Dies bietet einen erheblichen Vorteil in Bezug auf die Barrierefreiheit, da kein horizontales Schwenken und keine frustrierende Zickzackbewegung erforderlich ist, die sonst zum Lesen langer Textzeilen erforderlich wäre.

Weitere Informationen: Studien haben ergeben, dass Inhalte, die für Nutzer mit eingeschränktem Sehvermögen umgebrochen werden, deutlich besser lesbar und einfacher zu navigieren sind als Oberflächen, die zweidimensionales Schwenken erfordern. Weitere Informationen finden Sie unter A Comparison of Pan-and-Scan and Reflowable Content on Mobile Devices.

Alle Elemente oder nur Textelemente skalieren

In der folgenden Tabelle sehen Sie die visuellen Auswirkungen der einzelnen Skalierungsstrategien.

Strategie Skalierung der Pixeldichte Schriftskalierung

Verhalten

Skaliert alles proportional. Der Inhalt wird so umgebrochen, dass er in den Container passt. Der Nutzer muss also nicht horizontal schwenken, um alle Inhalte zu sehen.

Wirkt sich nur auf Textelemente aus. Das Gesamtdesign und die nicht textbasierten Komponenten bleiben gleich groß.

Waagen

Alle visuellen Elemente: Text, Komponenten (Schaltflächen, Symbole), Bilder und Layoutabstände (Innen- und Außenabstand)

Nur Text

Demonstration

Empfehlungen

Nachdem Sie die visuellen Unterschiede gesehen haben, können Sie anhand der folgenden Tabelle die Vor- und Nachteile abwägen und die beste Strategie für Ihre Inhalte auswählen.

UI-Typ

Empfohlene Strategie

Logisches Denken

Layouts mit viel Text

Beispiele: Nachrichtenartikel, Messaging-Apps

Dichte oder Schriftskalierung

Die Dichteskalierung wird bevorzugt, um den gesamten Inhaltsbereich, einschließlich Inline-Bildern, zu skalieren.

Die Schriftartskalierung ist eine einfache Alternative, wenn nur Text skaliert werden muss.

Visuell strukturierte Layouts

Beispiele: App-Shops, Feeds in sozialen Medien

Skalierung der Dichte

Die visuellen Beziehungen zwischen Bildern und Text in Karussells oder Rastern bleiben erhalten. Durch das Umfließen wird horizontales Schwenken vermieden, das mit verschachtelten Scrolling-Elementen in Konflikt stehen würde.

Skalierungsgesten in Jetpack Compose erkennen

Um skalierbaren Content zu unterstützen, müssen Sie zuerst Multitouch-Gesten erkennen. In Jetpack Compose können Sie dazu die Modifier.transformable verwenden.

Der Modifikator transformable ist eine API auf hoher Ebene, die das zoomChange-Delta seit dem letzten Gestenereignis bereitstellt. Dadurch wird die Logik für die Aktualisierung des Status vereinfacht, da die Werte direkt kumuliert werden (z. B. scale *= zoomChange). Das ist ideal für die in diesem Leitfaden beschriebenen adaptiven Skalierungsstrategien.

Beispielimplementierungen

Die folgenden Beispiele zeigen, wie die Strategien für die Dichte- und Schriftartskalierung implementiert werden.

Skalierung der Pixeldichte

Bei diesem Ansatz wird die Basis-density eines UI-Bereichs skaliert. Daher werden alle layoutbasierten Messungen skaliert, einschließlich Padding, Abständen und Komponentengrößen, als ob sich die Bildschirmgröße oder ‑auflösung geändert hätte. Da die Textgröße auch von der Dichte abhängt, wird sie ebenfalls proportional skaliert. Diese Strategie ist effektiv, wenn Sie alle Elemente in einem bestimmten Bereich einheitlich vergrößern möchten, wobei der visuelle Rhythmus und die Proportionen der Benutzeroberfläche beibehalten werden.

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
        )
    }
}

Schriftskalierung

Diese Strategie ist zielgerichteter, da nur der Faktor fontScale geändert wird. Das Ergebnis ist, dass nur Textelemente vergrößert oder verkleinert werden, während alle anderen Layoutkomponenten wie Container, Padding und Symbole eine feste Größe behalten. Diese Strategie eignet sich gut, um die Lesbarkeit von Text in Apps zu verbessern, in denen viel gelesen wird.

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
        )
    }
}

Gemeinsame Demo-UI

Dies ist die gemeinsame zusammensetzbare Funktion DemoCard, die in den beiden vorherigen Beispielen verwendet wird, um die unterschiedlichen Skalierungsverhalten hervorzuheben.

@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
            )
        }
    }
}

Tipps und wichtige Aspekte

Mit den folgenden Empfehlungen können Sie eine ansprechendere und barrierefreie User Experience schaffen:

  • Bieten Sie alternative Steuerungsmöglichkeiten für die Skalierung an: Einige Nutzer haben möglicherweise Schwierigkeiten mit Gesten. Um diese Nutzer zu unterstützen, sollten Sie eine alternative Möglichkeit zum Anpassen oder Zurücksetzen der Skalierung anbieten, die nicht auf Gesten basiert.
  • Für alle Skalierungen entwickeln: Testen Sie die Benutzeroberfläche sowohl mit der In-App-Skalierung als auch mit den systemweiten Schrift- oder Anzeigeeinstellungen. Prüfen Sie, ob sich die Layouts Ihrer App korrekt anpassen, ohne dass Inhalte unterbrochen, überlappt oder verborgen werden. Weitere Informationen zum Erstellen adaptiver Layouts