In vielen Apps müssen Sammlungen von Elementen angezeigt werden. In diesem Dokument wird erläutert, wie Sie dies effizient in Jetpack Compose erledigen können.
Wenn Sie wissen, dass für Ihren Anwendungsfall kein Scrollen erforderlich ist, können Sie ein einfaches Column
oder Row
(je nach Richtung) verwenden und den Inhalt jedes Elements ausgeben, indem Sie eine Liste wie diese durchlaufen:
@Composable fun MessageList(messages: List<Message>) { Column { messages.forEach { message -> MessageRow(message) } } }
Mit dem verticalScroll()
-Modifikator können wir Column
scrollbar machen.
Weitere Informationen finden Sie in der Dokumentation zu Gesten.
Lazy 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 sind und unabhängig davon, ob sie sichtbar sind, dargestellt werden.
„Compose“ bietet eine Reihe von Komponenten, mit denen nur Elemente erstellt 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 die Elemente angeordnet und gescrollt werden. LazyColumn
erzeugt eine vertikal scrollbare Liste und LazyRow
eine horizontal scrollende Liste.
Die Lazy-Komponenten unterscheiden sich von den meisten Layouts in Compose. Statt einen @Composable
-Inhaltsblockparameter zu akzeptieren, sodass Apps zusammensetzbare Funktionen direkt ausgeben können, stellen die Lazy-Komponenten einen LazyListScope.()
-Block bereit. Dieser LazyListScope
-Block bietet eine DSL, mit der Apps den Inhalt des Artikels beschreiben können. Die Lazy-Komponente ist dann dafür verantwortlich, den Inhalt jedes Elements entsprechend dem Layout und der Scrollposition hinzuzufügen.
LazyListScope
DSL
Der DSL von LazyListScope
bietet eine Reihe von Funktionen zum Beschreiben von Elementen im Layout. Am einfachsten 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") } }
Außerdem gibt es eine Reihe von Erweiterungsfunktionen, mit denen sich Sammlungen von Elementen hinzufügen lassen, z. B. eine List
. Mit diesen Erweiterungen können wir das obige Column
-Beispiel einfach migrieren:
/** * import androidx.compose.foundation.lazy.items */ LazyColumn { items(messages) { message -> MessageRow(message) } }
Es gibt auch eine Variante der Erweiterungsfunktion items()
mit dem Namen 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 Darstellung von Elementen in einem Raster. Bei einem Lazy vertikalen Raster werden die Elemente in einem vertikal scrollbaren Container angezeigt, der sich über mehrere Spalten erstreckt. Das Lazy horizontale Raster hingegen verhält sich auf der horizontalen Achse gleich.
Raster haben die gleichen leistungsstarken API-Funktionen wie Listen und verwenden außerdem eine sehr ähnliche DSL – LazyGridScope.()
zur Beschreibung des Inhalts.
Der Parameter columns
in LazyVerticalGrid
und der Parameter rows
in LazyHorizontalGrid
steuern, wie Zellen in Spalten oder Zeilen umgewandelt werden. Im folgenden Beispiel werden Elemente in einem Raster dargestellt. Dabei wird mit GridCells.Adaptive
festgelegt, dass jede Spalte mindestens 128.dp
breit ist:
LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 128.dp) ) { items(photos) { photo -> PhotoItem(photo) } }
Mit LazyVerticalGrid
können Sie eine Breite für Elemente angeben. Dann passt das Raster in so viele Spalten wie möglich. Die verbleibende Breite wird gleichmäßig auf die Spalten verteilt, nachdem die Anzahl der Spalten berechnet wurde.
Diese adaptive Art der Größenanpassung ist besonders nützlich, um Gruppen von Elementen verschiedener Bildschirmgrößen darzustellen.
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 in Ihrem Design nur bestimmte Elemente nicht standardmäßige Abmessungen haben müssen, können Sie die Rasterunterstützung verwenden, um benutzerdefinierte Spaltenspannen für Elemente anzugeben.
Geben Sie den Spaltenbereich mit dem Parameter span
der Methoden LazyGridScope DSL
item
und items
an.
maxLineSpan
, einer der Werte des Span-Bereichs, ist besonders nützlich, wenn Sie die adaptive Größenanpassung verwenden, 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, gestaffeltes Raster
LazyVerticalStaggeredGrid
und LazyHorizontalStaggeredGrid
sind zusammensetzbare Funktionen, mit denen Sie ein Lazy-Loading-Raster von Elementen erstellen können.
Bei einem vertikal gestaffelten vertikalen Raster werden die Elemente in einem vertikal scrollbaren Container angezeigt, der sich über mehrere Spalten erstreckt und einzelne Elemente unterschiedliche Höhen ermöglicht. Lazy horizontale Raster haben auf der horizontalen Achse dasselbe Verhalten bei Elementen unterschiedlicher Breite.
Das folgende Snippet ist ein einfaches Beispiel für die Verwendung von LazyVerticalStaggeredGrid
mit einer Breite von 200.dp
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.
Dadurch wird die verfügbare Breite durch die Anzahl der Spalten (oder Zeilen für ein horizontales Raster) geteilt 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 im Inhalt
Manchmal müssen Sie an den Rändern des Inhalts einen Innenrand hinzufügen. Mit den verzögerten Komponenten können Sie 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 für die horizontalen Ränder (links und rechts) einen Abstand von 16.dp
und dann zum oberen und unteren Rand des Inhalts 8.dp
hinzu.
Dieser Abstand wird auf den Inhalt und nicht auf den LazyColumn
selbst angewendet. Im Beispiel oben wird für das erste Element ein Abstand von 8.dp
oben hinzugefügt, beim letzten Element wird unten ein Abstand von 8.dp
hinzugefügt und für alle Elemente wird links und rechts ein Abstand von 16.dp
angezeigt.
Abstand zwischen Inhalten
Für zusätzlichen Abstand zwischen Elementen können Sie Arrangement.spacedBy()
verwenden.
Im folgenden Beispiel wird zwischen den einzelnen Elementen ein Leerzeichen (4.dp
) eingefügt:
LazyColumn( verticalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
Gleiches gilt für LazyRow
:
LazyRow( horizontalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
Raster können jedoch sowohl vertikal als auch horizontal angeordnet werden:
LazyVerticalGrid( columns = GridCells.Fixed(2), verticalArrangement = Arrangement.spacedBy(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp) ) { items(photos) { item -> PhotoItem(item) } }
Artikelschlüssel
Standardmäßig wird der Status jedes Elements von der Position des Elements in der Liste oder dem Raster abhängig gemacht. Dies kann jedoch zu Problemen führen, wenn sich der Datensatz ändert, da Elemente, die ihre Position ändern, alle gespeicherten Elemente verlieren. Wenn Sie sich das Szenario von LazyRow
innerhalb einer LazyColumn
vorstellen und die Zeile die Position eines 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 und einen Block für den Parameter key
angeben. Wenn Sie einen stabilen Schlüssel angeben, ist der Elementstatus bei allen Datensatzänderungen einheitlich:
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 hilfst du Compose bei der korrekten Verarbeitung von Neuanordnungen. Wenn Ihr Element beispielsweise den Status „mered“ enthält, können Sie mit den Tastenkombination festlegen, dass dieser Status zusammen mit dem Element verschoben werden 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 Schlüsseltyp muss von Bundle
unterstützt werden. Dies ist der Mechanismus von Android zum Beibehalten des Status beim Neuerstellen der Aktivität. 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 die rememberSaveable
in der zusammensetzbaren Funktion des Elements wiederhergestellt werden kann, wenn die Aktivität neu erstellt wird oder wenn Sie vom Element weg scrollen und zurückscrollen.
LazyColumn { items(books, key = { it.id }) { val rememberedValue = rememberSaveable { Random.nextInt() } } }
Elementanimationen
Wenn Sie das RecyclerView-Widget verwendet haben, wissen Sie, dass es Elementä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 Modifikator animateItemPlacement
auf den Inhalt des Artikels festlegen:
LazyColumn { items(books, key = { it.id }) { Row(Modifier.animateItemPlacement()) { // ... } } }
Sie können sogar eine Spezifikation für benutzerdefinierte Animationen angeben, wenn Folgendes erforderlich ist:
LazyColumn { items(books, key = { it.id }) { Row( Modifier.animateItemPlacement( tween(durationMillis = 250) ) ) { // ... } } }
Achten Sie darauf, Schlüssel für die Elemente anzugeben, damit Sie die neue Position des verschobenen Elements finden können.
Abgesehen von Neuanordnungen befinden sich derzeit Animationen zum Hinzufügen und Entfernen von Elementen in der Entwicklung. Den Fortschritt können Sie unter Ausgabe 150812265 verfolgen.
Fixierte Überschriften (experimentell)
Das Muster „fixierte Kopfzeile“ ist bei der Anzeige von Listen gruppierter Daten hilfreich. Unten sehen Sie ein Beispiel für eine Kontaktliste, die nach den Anfangsbuchstaben jedes Kontakts gruppiert ist:
Um mit LazyColumn
einen fixierten Header zu erstellen, 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 Überschriften wie im obigen Beispiel mit der Kontaktliste zu erstellen, könnten 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 Änderungen an der Scrollposition und dem Layout von Elementen reagieren und darauf achten.
Die Lazy-Komponenten unterstützen diesen Anwendungsfall, indem sie LazyListState
hochziehen:
@Composable fun MessageList(messages: List<Message>) { // Remember our own LazyListState val listState = rememberLazyListState() // Provide it to LazyColumn LazyColumn(state = listState) { // ... } }
Bei einfachen Anwendungsfällen benötigen Apps normalerweise nur Informationen zum ersten sichtbaren Element. Für LazyListState
werden die Attribute firstVisibleItemIndex
und firstVisibleItemScrollOffset
bereitgestellt.
Wenn wir das Beispiel des Anzeigen- und Ausblendens einer Schaltfläche verwenden, je nachdem, ob die Nutzenden über das erste Element hinaus gescrollt haben:
@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 gängiges Beispiel dafür ist das Senden eines Analytics-Ereignisses, sobald der Nutzer an einem bestimmten Punkt weitergescrollt hat. Um dies effizient zu verarbeiten, 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 über das Attribut layoutInfo
auch Informationen zu allen aktuell angezeigten Elementen und ihren Grenzen auf dem Bildschirm bereit. Weitere Informationen finden Sie in der Klasse LazyListLayoutInfo
.
Scrollposition steuern
Es ist nicht nur sinnvoll, wenn Apps auf die Scrollposition reagieren, sondern auch die Scrollposition steuern können.
LazyListState
unterstützt dies über die Funktion scrollToItem()
, die „sofort“ die Scrollposition anfängt, und animateScrollToItem()
, die durch eine Animation scrollt (auch als flüssiges Scrollen bezeichnet):
@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 (Pging)
Mithilfe der Paging-Bibliothek können Apps umfangreiche Listen von Elementen unterstützen und kleine Listenabschnitte nach Bedarf laden und anzeigen. Ab Version 3.0 wird Compose über die androidx.paging:paging-compose
-Bibliothek unterstützt.
Um eine Liste der Seiteninhalte anzuzeigen, können wir die Erweiterungsfunktion collectAsLazyPagingItems()
verwenden und dann den zurückgegebenen LazyPagingItems
an items()
in unserem LazyColumn
übergeben. Ähnlich wie Paging-Unterstützung in Ansichten können Sie Platzhalter einblenden, 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 berücksichtigen können, damit Ihre Lazy-Layouts wie vorgesehen funktionieren.
Verwenden Sie keine Elemente mit einer Größe von 0 Pixeln.
Dies kann in Szenarien vorkommen, in denen Sie beispielsweise davon ausgehen, einige Daten wie Bilder asynchron abzurufen, um die Listenelemente später zu füllen. Dies würde dazu führen, dass das Lazy-Layout alle Elemente in der ersten Messung zusammensetzt, da ihre Höhe 0 Pixel beträgt und alle in den Darstellungsbereich passen könnten. Sobald die Elemente geladen und ihre Höhe maximiert wurden, werden in Lazy-Layouts alle anderen Elemente verworfen, die beim ersten Mal unnötigerweise zusammengesetzt wurden, da sie nicht in den Darstellungsbereich passen. Um dies zu vermeiden, sollten Sie eine Standardgrößenanpassung für Ihre Elemente festlegen, damit das Lazy-Layout korrekt berechnen kann, wie viele Elemente tatsächlich 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, sollten Sie darauf achten, dass die Größe der Elemente vor und nach dem Laden gleich bleibt. Fügen Sie beispielsweise einige Platzhalter hinzu. Dies trägt dazu bei, die korrekte Scrollposition beizubehalten.
Verschachteln Sie keine Komponenten, die in dieselbe Richtung gescrollt werden können.
Dies gilt nur, wenn scrollbare untergeordnete Elemente ohne eine vordefinierte Größe in einem anderen scrollbaren übergeordneten Element derselben Richtung verschachteln werden. Beispiel: Es wird versucht, ein untergeordnetes LazyColumn
ohne feste Höhe in einem vertikal scrollbaren übergeordneten Column
-Element zu verschachteln:
// throws IllegalStateException Column( modifier = Modifier.verticalScroll(state) ) { LazyColumn { // ... } }
Stattdessen können Sie dasselbe Ergebnis erzielen, indem Sie alle zusammensetzbaren Funktionen in eine übergeordnete LazyColumn
zusammenfassen und deren DSL verwenden, um verschiedene Inhaltstypen zu übergeben. Dadurch können sowohl einzelne Elemente als auch mehrere Listenelemente an einem Ort ausgegeben werden:
LazyColumn { item { Header() } items(data) { item -> PhotoItem(item) } item { Footer() } }
Zulässig sind Fälle, in denen verschiedene Richtungslayouts verschachteln sind, z. B. ein scrollbarer übergeordneter Row
und ein untergeordneter LazyColumn
:
Row( modifier = Modifier.horizontalScroll(scrollState) ) { LazyColumn { // ... } }
Das gilt auch für Fälle, in denen Sie weiterhin Layouts mit derselben Richtung 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) ) { // ... } }
Vorsicht, mehrere Elemente in einem Element zu platzieren
In diesem Beispiel gibt das zweite Lambda-Element zwei Elemente in einem Block aus:
LazyVerticalGrid( columns = GridCells.Adaptive(100.dp) ) { item { Item(0) } item { Item(1) Item(2) } item { Item(3) } // ... }
Lazy Layouts behandeln dies wie erwartet – sie legen Elemente nacheinander an, als wären sie verschiedene Elemente. Dabei gibt es jedoch ein paar Probleme.
Wenn mehrere Elemente als Teil eines Elements ausgegeben werden, werden sie als eine Entität behandelt, was bedeutet, dass sie nicht mehr einzeln zusammengestellt werden können. Wenn ein Element auf dem Bildschirm sichtbar wird, müssen alle Elemente, die dem Element entsprechen, zusammengesetzt und gemessen werden. Übermäßige Nutzung kann sich negativ auf die Leistung auswirken. Im Extremfall, dass alle Elemente in einem Element enthalten sind, widerspricht dies dem Zweck der Verwendung von Lazy-Layouts. Abgesehen von möglichen Leistungsproblemen kann es passieren, dass scrollToItem()
und animateScrollToItem()
beeinträchtigt werden, wenn mehr Elemente in einem Element enthalten sind.
Es gibt jedoch sinnvolle Anwendungsfälle für die Platzierung mehrerer Elemente in einem Element, z. B. Trennlinien in einer Liste. Trennlinien sollten die Scroll-Indexe nicht ändern, da sie nicht als unabhängige Elemente betrachtet werden sollten. Außerdem wird die Leistung nicht beeinträchtigt, da die Trennlinien klein sind. Eine Trennlinie muss wahrscheinlich sichtbar sein, wenn das Element davor sichtbar ist, damit sie Teil des vorherigen Elements sein können:
LazyVerticalGrid( columns = GridCells.Adaptive(100.dp) ) { item { Item(0) } item { Item(1) Divider() } item { Item(2) } // ... }
Individuelle Anordnungen in Betracht ziehen
In der Regel enthalten Lazy-Listen viele Elemente und belegen mehr als die Größe des scrollbaren Containers. Wenn Ihre Liste jedoch nur wenige Elemente enthält, können für Ihr Design spezifischere Anforderungen an die Positionierung dieser Elemente im Darstellungsbereich gelten.
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 die Elemente
nacheinander platziert. Wenn die insgesamt verwendete Höhe niedriger ist als die Höhe des Darstellungsbereichs, wird die Fußzeile unten 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() } } }
Du kannst „contentType
“ hinzufügen
Ab Compose 1.2 sollten Sie contentType
in Ihre Listen oder Raster aufnehmen, um die Leistung des Lazy-Layouts zu maximieren. So können Sie den Inhaltstyp für jedes Element des Layouts angeben, wenn Sie eine Liste oder ein Raster aus mehreren verschiedenen Elementtypen erstellen:
LazyColumn { items(elements, contentType = { it.type }) { // ... } }
Wenn Sie die contentType
angeben, kann Composer nur Kompositionen zwischen Elementen desselben Typs wiederverwenden. Da die Wiederverwendung effizienter ist, wenn Sie Elemente mit ähnlicher Struktur zusammensetzen, wird durch die Angabe der Inhaltstypen sichergestellt, dass Composer nicht versucht, ein Element des Typs A zusätzlich zu einem völlig anderen Element des Typs B zusammenzustellen. So können Sie die Vorteile der Wiederverwendung von Kompositionen und die Leistung des Lazy-Layouts maximieren.
Leistungsmessung
Sie können die Leistung eines Lazy-Layouts nur zuverlässig messen, wenn Sie im Release-Modus ausgeführt werden und die R8-Optimierung aktiviert ist. Bei Debug-Builds kann Lazy Layout Scrolling langsamer sein. Weitere Informationen dazu finden Sie unter Compose-Leistung.
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
RecyclerView
zur Lazy-Liste migrieren- UI-Status in „Compose“ speichern
- Kotlin für Jetpack Compose