In vielen Apps müssen Elemente in Sammlungen angezeigt werden. In diesem Dokument wird erläutert, wie Sie dies effizient in Jetpack Compose tun können.
Wenn Sie wissen, dass für Ihren Anwendungsfall kein Scrollen erforderlich ist, können Sie je nach Richtung ein einfaches Column
oder Row
verwenden und den Inhalt jedes Elements durch Iteration über eine Liste wie folgt ausgeben:
@Composable fun MessageList(messages: List<Message>) { Column { messages.forEach { message -> MessageRow(message) } } }
Column
lässt sich mit dem verticalScroll()
-Modifikator scrollbar machen.
Weitere Informationen finden Sie in der Dokumentation zu Gesten.
Verzögerte Listen
Wenn Sie eine große Anzahl von Elementen oder eine Liste mit unbekannter Länge anzeigen müssen, kann die Verwendung eines Layouts wie Column
zu Leistungsproblemen führen, da alle Elemente zusammengesetzt und angeordnet werden, unabhängig davon, ob sie sichtbar sind oder nicht.
Die Funktion „Compose“ umfasst eine Reihe von Komponenten, mit denen nur Elemente zusammengesetzt und angeordnet werden, die im Darstellungsbereich der Komponente sichtbar sind. Zu diesen Komponenten gehören LazyColumn
und LazyRow
.
Wie der Name schon sagt, besteht der Unterschied zwischen LazyColumn
und LazyRow
in der Ausrichtung, in der sie ihre Elemente anordnen und scrollen. LazyColumn
generiert eine vertikal scrollbare Liste und LazyRow
eine horizontal scrollbare Liste.
Die Lazy-Komponenten unterscheiden sich von den meisten Layouts in der Funktion „Compose“. Anstelle eines @Composable
-Inhaltsblockparameters, der es Apps ermöglicht, zusammensetzbare Funktionen direkt auszugeben, bieten die Lazy-Komponenten einen LazyListScope.()
-Block. Dieser LazyListScope
-Block bietet eine DSL, mit der Apps den Inhalt der Elemente beschreiben können. Die Lazy-Komponente ist dann dafür verantwortlich, den Inhalt der einzelnen Elemente entsprechend dem Layout und der Scrollposition hinzuzufügen.
LazyListScope
DSL
Die DSL von LazyListScope
bietet eine Reihe von Funktionen zum Beschreiben von Elementen im Layout. Im einfachsten Fall fügt item()
ein einzelnes Element und items(Int)
mehrere Elemente hinzu:
LazyColumn { // Add a single item item { Text(text = "First item") } // Add 5 items items(5) { index -> Text(text = "Item: $index") } // Add another single item item { Text(text = "Last item") } }
Es gibt auch eine Reihe von Erweiterungsfunktionen, mit denen Sie Sammlungen von Elementen hinzufügen können, z. B. eine List
. Mit diesen Erweiterungen lässt sich das obige Column
-Beispiel ganz einfach migrieren:
/** * import androidx.compose.foundation.lazy.items */ LazyColumn { items(messages) { message -> MessageRow(message) } }
Es gibt auch eine Variante der Erweiterungsfunktion items()
namens itemsIndexed()
, die den Index bereitstellt. Weitere Informationen finden Sie in der Referenz zu LazyListScope
.
Lazy Grids
Die zusammensetzbaren Funktionen LazyVerticalGrid
und LazyHorizontalGrid
unterstützen die Anzeige von Elementen in einem Raster. Bei einem Lazy-Vertical-Raster werden die Elemente in einem vertikal scrollbaren Container angezeigt, der sich über mehrere Spalten erstreckt. Lazy horizontale Raster verhalten sich auf der horizontalen Achse dagegen gleich.
Raster haben die gleichen leistungsstarken API-Funktionen wie Listen und verwenden außerdem eine sehr ähnliche DSL: LazyGridScope.()
zur Beschreibung des Inhalts.
Mit den Parametern columns
in LazyVerticalGrid
und dem Parameter rows
in LazyHorizontalGrid
wird gesteuert, wie Zellen in Spalten oder Zeilen gebildet werden. Im folgenden Beispiel werden Elemente in einem Raster dargestellt. Dabei wird mit GridCells.Adaptive
für jede Spalte mindestens eine Breite von 128.dp
festgelegt:
LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 128.dp) ) { items(photos) { photo -> PhotoItem(photo) } }
Mit LazyVerticalGrid
können Sie eine Breite für Elemente angeben. Anschließend passt das Raster so viele Spalten wie möglich an. Die verbleibende Breite wird gleichmäßig auf die Spalten verteilt, nachdem die Anzahl der Spalten berechnet wurde.
Diese adaptive Größenanpassung eignet sich besonders für die Anzeige von Elementen auf verschiedenen Bildschirmgrößen.
Wenn Sie die genaue Anzahl der zu verwendenden Spalten kennen, können Sie stattdessen eine Instanz von GridCells.Fixed
mit der Anzahl der erforderlichen Spalten angeben.
Wenn für Ihr Design nur bestimmte Elemente nicht standardmäßige Abmessungen benötigen, können Sie die Rasterunterstützung nutzen, um benutzerdefinierte Spaltenspannen für Elemente bereitzustellen.
Geben Sie den Spaltenbereich mit dem Parameter span
der Methoden LazyGridScope DSL
item
und items
an.
maxLineSpan
, einer der Werte des Span-Bereichs, ist bei Verwendung der adaptiven Größe besonders nützlich, da die Anzahl der Spalten nicht festgelegt ist.
In diesem Beispiel wird gezeigt, wie Sie einen vollständigen Zeilenbereich angeben:
LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 30.dp) ) { item(span = { // LazyGridItemSpanScope: // maxLineSpan GridItemSpan(maxLineSpan) }) { CategoryCard("Fruits") } // ... }
Verzögertes Raster
LazyVerticalStaggeredGrid
und LazyHorizontalStaggeredGrid
sind zusammensetzbare Funktionen, mit denen Sie ein Lazy-Loading-Raster von Elementen erstellen können.
Bei einem lazy vertikalen, gestaffelten Raster werden die Elemente in einem vertikal scrollbaren Container angezeigt, der sich über mehrere Spalten erstreckt und verschiedene Höhen einzelner Elemente ermöglicht. Verzögerte horizontale Raster verhalten sich auf der horizontalen Achse gleich, wenn Elemente unterschiedlich breit sind.
Das folgende Snippet ist ein einfaches Beispiel für die Verwendung von LazyVerticalStaggeredGrid
mit einer 200.dp
-Breite pro Element:
LazyVerticalStaggeredGrid( columns = StaggeredGridCells.Adaptive(200.dp), verticalItemSpacing = 4.dp, horizontalArrangement = Arrangement.spacedBy(4.dp), content = { items(randomSizedPhotos) { photo -> AsyncImage( model = photo, contentScale = ContentScale.Crop, contentDescription = null, modifier = Modifier.fillMaxWidth().wrapContentHeight() ) } }, modifier = Modifier.fillMaxSize() )
Wenn Sie eine feste Anzahl von Spalten festlegen möchten, können Sie StaggeredGridCells.Fixed(columns)
anstelle von StaggeredGridCells.Adaptive
verwenden.
Die verfügbare Breite wird durch die Anzahl der Spalten (oder Zeilen bei einem horizontalen Raster) dividiert und jedes Element nimmt diese Breite (bzw. Höhe bei einem horizontalen Raster) ein:
LazyVerticalStaggeredGrid( columns = StaggeredGridCells.Fixed(3), verticalItemSpacing = 4.dp, horizontalArrangement = Arrangement.spacedBy(4.dp), content = { items(randomSizedPhotos) { photo -> AsyncImage( model = photo, contentScale = ContentScale.Crop, contentDescription = null, modifier = Modifier.fillMaxWidth().wrapContentHeight() ) } }, modifier = Modifier.fillMaxSize() )
Abstände zwischen Inhalten
Manchmal müssen Sie an den Rändern des Inhalts einen Innenrand hinzufügen. Mit den verzögerten Komponenten können Sie einige PaddingValues
an den Parameter contentPadding
übergeben, um dies zu unterstützen:
LazyColumn( contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp), ) { // ... }
In diesem Beispiel fügen wir den horizontalen Kanten (links und rechts) einen Innenabstand von 16.dp
und dann 8.dp
am oberen und unteren Rand des Inhalts hinzu.
Dieser Abstand wird auf den Inhalt angewendet, nicht auf den LazyColumn
selbst. Im Beispiel oben fügt das erste Element am oberen Rand einen Abstand von 8.dp
hinzu. Das letzte Element fügt am unteren Rand 8.dp
hinzu. Alle Elemente haben links und rechts einen Abstand von 16.dp
.
Abstand zwischen Inhalten
Mit Arrangement.spacedBy()
können Sie den Abstand zwischen Elementen vergrößern.
Im folgenden Beispiel wird zwischen den einzelnen Elementen ein Leerzeichen von 4.dp
hinzugefügt:
LazyColumn( verticalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
Ähnliches gilt für LazyRow
:
LazyRow( horizontalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
Raster unterstützen jedoch sowohl vertikale als auch horizontale Anordnungen:
LazyVerticalGrid( columns = GridCells.Fixed(2), verticalArrangement = Arrangement.spacedBy(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp) ) { items(photos) { item -> PhotoItem(item) } }
Elementschlüssel
Standardmäßig ist der Status jedes Elements von der Position des Elements in der Liste oder dem Raster abhängig. Dies kann jedoch zu Problemen führen, wenn sich der Datensatz ändert, da Elemente, die sich an ihrer Position ändern, effektiv ihren gespeicherten Status verlieren. Wenn Sie sich das Szenario von LazyRow
innerhalb einer LazyColumn
vorstellen und die Zeile die Position des Elements ändert, würde der Nutzer seine Scrollposition innerhalb der Zeile verlieren.
Um dies zu verhindern, können Sie für jedes Element einen stabilen und eindeutigen Schlüssel angeben und einen Block für den Parameter key
bereitstellen. Wenn Sie einen stabilen Schlüssel angeben, ist der Elementstatus bei allen Datensatzänderungen konsistent:
LazyColumn { items( items = messages, key = { message -> // Return a stable + unique key for the item message.id } ) { message -> MessageRow(message) } }
Durch die Angabe von Schlüsseln kann Compose Neuanordnungen richtig verarbeiten. Wenn Ihr Element beispielsweise einen gespeicherten Status enthält, können die Schlüssel festgelegt werden, dass Composer diesen Status zusammen mit dem Element verschieben kann, wenn sich seine Position ändert.
LazyColumn { items(books, key = { it.id }) { val rememberedValue = remember { Random.nextInt() } } }
Es gibt jedoch eine Einschränkung hinsichtlich der Typen, die Sie als Elementschlüssel verwenden können.
Der Typ des Schlüssels muss von Bundle
unterstützt werden, dem Mechanismus von Android, mit dem der Status beim Neuerstellen der Aktivität beibehalten wird. Bundle
unterstützt Typen wie Primitive, Enums oder Parcelables.
LazyColumn { items(books, key = { // primitives, enums, Parcelable, etc. }) { // ... } }
Der Schlüssel muss von Bundle
unterstützt werden, damit rememberSaveable
innerhalb der zusammensetzbaren Funktion wiederhergestellt werden kann, wenn die Aktivität neu erstellt wird oder wenn Sie von diesem Element weg scrollen und zurückscrollen.
LazyColumn { items(books, key = { it.id }) { val rememberedValue = rememberSaveable { Random.nextInt() } } }
Artikelanimationen
Wenn Sie das RecyclerView-Widget verwendet haben, wissen Sie, dass es Artikeländerungen automatisch animiert.
Lazy Layouts bieten die gleiche Funktionalität für die Neuanordnung von Elementen.
Die API ist einfach. Sie müssen nur den animateItemPlacement
-Modifikator auf den Elementinhalt setzen:
LazyColumn { items(books, key = { it.id }) { Row(Modifier.animateItemPlacement()) { // ... } } }
Sie können sogar eine benutzerdefinierte Animationsspezifikation bereitstellen, wenn Sie:
LazyColumn { items(books, key = { it.id }) { Row( Modifier.animateItemPlacement( tween(durationMillis = 250) ) ) { // ... } } }
Geben Sie Schlüssel für Ihre Elemente an, damit Sie die neue Position des verschobenen Elements finden können.
Abgesehen von Neuanordnungen befindet sich die Entwicklung derzeit an Animationen für Hinzufügungen und Entfernungen. Sie können den Fortschritt unter Problem 150812265 verfolgen.
Fixierte Überschriften (experimentell)
Das Muster für eine fixierte Kopfzeile ist hilfreich, wenn Listen gruppierter Daten angezeigt werden. Im Folgenden sehen Sie ein Beispiel für eine Kontaktliste, die nach der Anfangsbuchstaben der jeweiligen Kontakte gruppiert ist:
Um einen fixierten Header mit LazyColumn
zu erhalten, können Sie die experimentelle Funktion stickyHeader()
verwenden und den Inhalt des Headers angeben:
@OptIn(ExperimentalFoundationApi::class) @Composable fun ListWithHeader(items: List<Item>) { LazyColumn { stickyHeader { Header() } items(items) { item -> ItemRow(item) } } }
Um eine Liste mit mehreren Headern zu erstellen, wie im Beispiel für die Kontaktliste oben, können Sie Folgendes tun:
// This ideally would be done in the ViewModel val grouped = contacts.groupBy { it.firstName[0] } @OptIn(ExperimentalFoundationApi::class) @Composable fun ContactsList(grouped: Map<Char, List<Contact>>) { LazyColumn { grouped.forEach { (initial, contactsForInitial) -> stickyHeader { CharacterHeader(initial) } items(contactsForInitial) { contact -> ContactListItem(contact) } } } }
Auf Scrollposition reagieren
Viele Apps müssen auf Scrollpositionen und Layoutänderungen von Elementen reagieren und darauf reagieren.
Die Lazy-Komponenten unterstützen diesen Anwendungsfall durch das Hochziehen der LazyListState
:
@Composable fun MessageList(messages: List<Message>) { // Remember our own LazyListState val listState = rememberLazyListState() // Provide it to LazyColumn LazyColumn(state = listState) { // ... } }
Für einfache Anwendungsfälle müssen Anwendungen in der Regel nur Informationen über das erste sichtbare Element kennen. Dazu stellt LazyListState
die Attribute firstVisibleItemIndex
und firstVisibleItemScrollOffset
bereit.
Nehmen wir als Beispiel das Anzeigen und Ausblenden einer Schaltfläche, je nachdem, ob der Nutzer am ersten Element vorbeigescrollt hat:
@OptIn(ExperimentalAnimationApi::class) @Composable fun MessageList(messages: List<Message>) { Box { val listState = rememberLazyListState() LazyColumn(state = listState) { // ... } // Show the button if the first visible item is past // the first item. We use a remembered derived state to // minimize unnecessary compositions val showButton by remember { derivedStateOf { listState.firstVisibleItemIndex > 0 } } AnimatedVisibility(visible = showButton) { ScrollToTopButton() } } }
Es ist nützlich, den Status direkt in der Zusammensetzung zu lesen, wenn Sie andere zusammensetzbare UI-Elemente aktualisieren müssen. Es gibt aber auch Szenarien, in denen das Ereignis nicht in derselben Zusammensetzung verarbeitet werden muss. Ein Beispiel dafür ist das Senden eines Analyseereignisses, wenn der Nutzer an einem bestimmten Punkt vorbeigescrollt hat. Um dies effizient zu handhaben, können wir einen snapshotFlow()
verwenden:
val listState = rememberLazyListState() LazyColumn(state = listState) { // ... } LaunchedEffect(listState) { snapshotFlow { listState.firstVisibleItemIndex } .map { index -> index > 0 } .distinctUntilChanged() .filter { it } .collect { MyAnalyticsService.sendScrolledPastFirstItemEvent() } }
LazyListState
stellt außerdem über die Property layoutInfo
Informationen zu allen derzeit angezeigten Elementen und ihren Grenzen auf dem Bildschirm bereit. Weitere Informationen finden Sie in der Klasse LazyListLayoutInfo
.
Scrollposition festlegen
Neben der Reaktion auf die Scrollposition ist es auch nützlich, dass Apps die Scrollposition steuern können.
LazyListState
unterstützt dies über die Funktion scrollToItem()
, die „sofort“ die Scrollposition anklickt, und animateScrollToItem()
, die mithilfe einer Animation (auch als Smooth Scrollen bezeichnet) scrollt:
@Composable fun MessageList(messages: List<Message>) { val listState = rememberLazyListState() // Remember a CoroutineScope to be able to launch val coroutineScope = rememberCoroutineScope() LazyColumn(state = listState) { // ... } ScrollToTopButton( onClick = { coroutineScope.launch { // Animate scroll to the first item listState.animateScrollToItem(index = 0) } } ) }
Große Datensätze (Paging)
Mit der Paging-Bibliothek können Anwendungen umfangreiche Listen von Elementen unterstützen und kleine Listenelemente nach Bedarf laden und anzeigen. Paging 3.0 und höher bieten Unterstützung für das Verfassen über die androidx.paging:paging-compose
-Bibliothek.
Zum Anzeigen einer Liste mit Seiteninhalten können Sie die Erweiterungsfunktion collectAsLazyPagingItems()
verwenden und dann das zurückgegebene LazyPagingItems
-Element an items()
in der LazyColumn
übergeben. Ähnlich wie die Paginierungsunterstützung in Ansichten können Sie Platzhalter anzeigen lassen, während Daten geladen werden. Prüfen Sie dazu, ob item
auf null
gesetzt ist:
@Composable fun MessageList(pager: Pager<Int, Message>) { val lazyPagingItems = pager.flow.collectAsLazyPagingItems() LazyColumn { items( lazyPagingItems.itemCount, key = lazyPagingItems.itemKey { it.id } ) { index -> val message = lazyPagingItems[index] if (message != null) { MessageRow(message) } else { MessagePlaceholder() } } } }
Tipps zur Verwendung von Lazy-Layouts
Es gibt einige Tipps, die Sie beachten können, damit Ihre Lazy-Layouts wie vorgesehen funktionieren.
Verwenden Sie keine Elemente mit der Größe 0 Pixel.
Dies kann z. B. der Fall sein, wenn Sie beispielsweise erwarten, einige Daten wie Bilder asynchron abzurufen, um die Elemente Ihrer Liste zu einem späteren Zeitpunkt zu füllen. Das würde dazu führen, dass beim Lazy-Layout alle Elemente in der ersten Messung zusammengefügt werden, da ihre Höhe 0 Pixel beträgt und sie alle in den Darstellungsbereich passen könnten. Sobald die Elemente geladen und ihre Höhe erweitert wurde, würden Lazy-Layouts alle anderen Elemente verwerfen, die beim ersten Mal unnötigerweise zusammengestellt wurden, da sie nicht in den Darstellungsbereich passen. Um dies zu vermeiden, sollten Sie die Standardgröße für Ihre Elemente festlegen, damit mit dem Lazy-Layout richtig berechnet werden kann, wie viele Elemente in den Darstellungsbereich passen:
@Composable fun Item(imageUrl: String) { AsyncImage( model = rememberAsyncImagePainter(model = imageUrl), modifier = Modifier.size(30.dp), contentDescription = null // ... ) }
Wenn Sie die ungefähre Größe Ihrer Elemente kennen, nachdem die Daten asynchron geladen wurden, empfiehlt es sich, dafür zu sorgen, dass die Größe der Elemente vor und nach dem Laden gleich bleibt. Fügen Sie beispielsweise Platzhalter hinzu. Dies trägt dazu bei, die richtige Scrollposition beizubehalten.
Vermeiden Sie es, Komponenten zu verschachteln, die in die gleiche Richtung gescrollt werden können.
Das gilt nur für Fälle, in denen scrollbare untergeordnete Elemente ohne vordefinierte Größe innerhalb eines übergeordneten Elements in derselben Richtung verschachtelt werden. Beispiel: Sie versuchen, ein untergeordnetes LazyColumn
-Element ohne feste Höhe in einem vertikal scrollbaren Column
-Element zu verschachteln:
// throws IllegalStateException Column( modifier = Modifier.verticalScroll(state) ) { LazyColumn { // ... } }
Stattdessen können Sie das gleiche Ergebnis erzielen, wenn Sie alle zusammensetzbaren Funktionen in eine übergeordnete LazyColumn
zusammenfassen und deren DSL verwenden, um verschiedene Inhaltstypen zu übergeben. Dadurch können einzelne Elemente sowie mehrere Listenelemente an einem Ort ausgegeben werden:
LazyColumn { item { Header() } items(data) { item -> PhotoItem(item) } item { Footer() } }
In Fällen, in denen Sie unterschiedliche Richtungslayouts verschachteln, z. B. ein scrollbares übergeordnetes Row
und ein untergeordnetes LazyColumn
, sind zulässig:
Row( modifier = Modifier.horizontalScroll(scrollState) ) { LazyColumn { // ... } }
Das gilt auch für Fälle, in denen Sie weiterhin dieselben Richtungslayouts verwenden, aber auch eine feste Größe für die verschachtelten untergeordneten Elemente festlegen:
Column( modifier = Modifier.verticalScroll(scrollState) ) { LazyColumn( modifier = Modifier.height(200.dp) ) { // ... } }
Vermeiden Sie es, mehrere Elemente für einen Artikel zu verwenden.
In diesem Beispiel gibt das zweite Lambda-Element 2 Elemente in einem Block aus:
LazyVerticalGrid( columns = GridCells.Adaptive(100.dp) ) { item { Item(0) } item { Item(1) Item(2) } item { Item(3) } // ... }
Bei Lazy-Layouts wird dies wie erwartet gehandhabt – sie ordnen die Elemente nacheinander an, als wären es verschiedene Elemente. Dabei gibt es jedoch ein paar Probleme.
Wenn mehrere Elemente als Teil eines Elements ausgegeben werden, werden sie als eine Einheit behandelt, was bedeutet, dass sie nicht mehr einzeln zusammengesetzt werden können. Wenn ein Element auf dem Bildschirm sichtbar wird, müssen alle Elemente, die diesem Element entsprechen, zusammengesetzt und gemessen werden. Dies kann bei übermäßiger Verwendung die Leistung beeinträchtigen. Im Extremfall, bei dem alle Elemente in einem Element enthalten sind, verfehlt es den Zweck von Lazy-Layouts. Wenn mehr Elemente in einem Element enthalten sind, beeinträchtigt das nicht nur die potenziellen Leistungsprobleme, sondern auch scrollToItem()
und animateScrollToItem()
.
Es gibt jedoch zulässige Anwendungsfälle für die Aufnahme mehrerer Elemente in ein Element, z. B. Trennlinien innerhalb einer Liste. Durch Trennlinien werden Scroll-Indizes nicht verändert, denn sie sollten nicht als unabhängige Elemente Außerdem wird die Leistung nicht beeinträchtigt, da die Trennlinien klein sind. Eine Trennlinie muss wahrscheinlich sichtbar sein, wenn das Element vorher sichtbar ist, damit sie Teil des vorherigen Elements sein kann:
LazyVerticalGrid( columns = GridCells.Adaptive(100.dp) ) { item { Item(0) } item { Item(1) Divider() } item { Item(2) } // ... }
Benutzerdefinierte Anordnungen in Betracht ziehen
In der Regel umfassen Lazy-Listen viele Elemente und belegen mehr als die Größe des Scroll-Containers. Wenn Ihre Liste jedoch nur wenige Elemente enthält, kann Ihr Design spezifischere Anforderungen an die Positionierung dieser Elemente im Darstellungsbereich stellen.
Dazu können Sie die benutzerdefinierte Branche Arrangement
verwenden und an LazyColumn
übergeben. Im folgenden Beispiel muss für das TopWithFooter
-Objekt nur die Methode arrange
implementiert werden. Erstens werden Elemente
nacheinander platziert. Wenn außerdem die gesamte verwendete Höhe niedriger als die Höhe des Darstellungsbereichs ist, wird die Fußzeile am unteren Rand platziert:
object TopWithFooter : Arrangement.Vertical { override fun Density.arrange( totalSize: Int, sizes: IntArray, outPositions: IntArray ) { var y = 0 sizes.forEachIndexed { index, size -> outPositions[index] = y y += size } if (y < totalSize) { val lastIndex = outPositions.lastIndex outPositions[lastIndex] = totalSize - sizes.last() } } }
Wir empfehlen, contentType
hinzuzufügen
Ab Compose 1.2 können Sie contentType
in Listen oder Raster aufnehmen, um die Leistung Ihres Lazy-Layouts zu maximieren. Auf diese Weise können Sie den Inhaltstyp für jedes Element des Layouts angeben, wenn Sie eine Liste oder ein Raster zusammenstellen, das aus mehreren verschiedenen Arten von Elementen besteht:
LazyColumn { items(elements, contentType = { it.type }) { // ... } }
Wenn Sie contentType
angeben, kann Composer nur Kompositionen zwischen Elementen desselben Typs wiederverwenden. Da Wiederverwendung effizienter ist, wenn Sie Elemente mit ähnlicher Struktur erstellen, wird durch Angabe der Inhaltstypen sichergestellt, dass in Composer nicht versucht, ein Element vom Typ A über ein komplett anderes Element von Typ B zu erstellen. So können Sie die Vorteile der Wiederverwendung von Kompositionen und die Leistung des Lazy-Layouts optimal nutzen.
Leistungsmessung
Sie können die Leistung eines Lazy-Layouts nur dann zuverlässig messen, wenn es im Release-Modus ausgeführt wird und die R8-Optimierung aktiviert ist. Bei Debug-Builds erscheint das Lazy Layout Scrolling möglicherweise langsamer. Weitere Informationen dazu finden Sie unter Compose-Leistung.
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
RecyclerView
zu Lazy-Liste migrieren- UI-Status in „Compose“ speichern
- Kotlin für Jetpack Compose