Pager in der Funktion „Schreiben“

Um nach links und rechts oder nach oben und unten durch Inhalte zu blättern, können Sie die HorizontalPager und VerticalPager zusammensetzbare Funktionen verwenden. Diese zusammensetzbaren Funktionen haben ähnliche Funktionen wie ViewPager in der Ansicht System. Standardmäßig nimmt HorizontalPager die volle Breite des Bildschirms ein. VerticalPager nimmt die gesamte Höhe ein und die Pager schlagen jeweils nur eine Seite auf. . Diese Standardeinstellungen sind konfigurierbar.

HorizontalPager

Um einen Pager zu erstellen, der horizontal nach links und rechts scrollt, verwenden Sie HorizontalPager:

Abbildung 1: Demo von HorizontalPager

// Display 10 items
val pagerState = rememberPagerState(pageCount = {
    10
})
HorizontalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier.fillMaxWidth()
    )
}

VerticalPager

Verwenden Sie VerticalPager, um einen Pager zu erstellen, der nach oben und unten scrollt:

Abbildung 2: Demo von VerticalPager

// Display 10 items
val pagerState = rememberPagerState(pageCount = {
    10
})
VerticalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier.fillMaxWidth()
    )
}

Verzögerte Erstellung

Die Seiten in HorizontalPager und VerticalPager sind faszinierend erstellt und bei Bedarf angeordnet. Als Nutzer durch die Seiten scrollt, entfernt die zusammensetzbare Funktion alle Seiten, die nicht mehr erforderlich.

Weitere Seiten außerhalb des Bildschirms laden

Standardmäßig werden auf dem Pager nur die sichtbaren Seiten auf dem Bildschirm geladen. So laden Sie weitere Seiten nicht zu sehen sein, stellen Sie beyondBoundsPageCount auf einen Wert größer null ein.

Zu einem Element auf der Seite scrollen

Um im Pager zu einer bestimmten Seite zu scrollen, erstellen Sie PagerState mithilfe von rememberPagerState() und übergeben Sie ihn als state-Parameter an den Pager. Sie können PagerState#scrollToPage() für diesen Status in CoroutineScope:

val pagerState = rememberPagerState(pageCount = {
    10
})
HorizontalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier
            .fillMaxWidth()
            .height(100.dp)
    )
}

// scroll to page
val coroutineScope = rememberCoroutineScope()
Button(onClick = {
    coroutineScope.launch {
        // Call scroll to on pagerState
        pagerState.scrollToPage(5)
    }
}, modifier = Modifier.align(Alignment.BottomCenter)) {
    Text("Jump to Page 5")
}

Wenn Sie die Seite animieren möchten, verwenden Sie die Methode PagerState#animateScrollToPage() :

val pagerState = rememberPagerState(pageCount = {
    10
})

HorizontalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier
            .fillMaxWidth()
            .height(100.dp)
    )
}

// scroll to page
val coroutineScope = rememberCoroutineScope()
Button(onClick = {
    coroutineScope.launch {
        // Call scroll to on pagerState
        pagerState.animateScrollToPage(5)
    }
}, modifier = Modifier.align(Alignment.BottomCenter)) {
    Text("Jump to Page 5")
}

Benachrichtigungen zu Änderungen des Seitenstatus erhalten

PagerState hat drei Eigenschaften mit Informationen zu Seiten: currentPage settledPage, und targetPage

  • currentPage: Die Seite, die der Andockposition am nächsten ist. Standardmäßig ist das Andocken Position am Anfang des Layouts ist.
  • settledPage: Die Seitenzahl, wenn keine Animation oder kein Scrollen ausgeführt wird. Dieses unterscheidet sich von der currentPage-Eigenschaft insofern, als die currentPage wird sofort aktualisiert, wenn die Seite nah genug an der Andockposition ist, settledPage bleibt gleich, bis alle Animationen ausgeführt wurden.
  • targetPage: Die vorgeschlagene Stoppposition für eine Scrollbewegung.

Mit der Funktion snapshotFlow können Sie Änderungen an diesen Variablen beobachten. und darauf zu reagieren. Wenn Sie beispielsweise ein Analytics-Ereignis bei jeder Seitenänderung senden möchten, können Sie Folgendes tun:

val pagerState = rememberPagerState(pageCount = {
    10
})

LaunchedEffect(pagerState) {
    // Collect from the a snapshotFlow reading the currentPage
    snapshotFlow { pagerState.currentPage }.collect { page ->
        // Do something with each page change, for example:
        // viewModel.sendPageSelectedEvent(page)
        Log.d("Page change", "Page changed to $page")
    }
}

VerticalPager(
    state = pagerState,
) { page ->
    Text(text = "Page: $page")
}

Seitenwechsel hinzufügen

Wenn du einer Seite einen Indikator hinzufügen möchtest, verwende das PagerState-Objekt, um Informationen abzurufen welche Seite aus der Anzahl von Seiten ausgewählt wird, und zeichnen Sie .

Wenn Sie zum Beispiel eine einfache Kreisanzeige wünschen, können Sie die Anzahl der und ändern Sie die Farbe des Kreises, je nachdem, ob Sie die Seite ausgewählt haben. pagerState.currentPage:

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    modifier = Modifier.fillMaxSize()
) { page ->
    // Our page content
    Text(
        text = "Page: $page",
    )
}
Row(
    Modifier
        .wrapContentHeight()
        .fillMaxWidth()
        .align(Alignment.BottomCenter)
        .padding(bottom = 8.dp),
    horizontalArrangement = Arrangement.Center
) {
    repeat(pagerState.pageCount) { iteration ->
        val color = if (pagerState.currentPage == iteration) Color.DarkGray else Color.LightGray
        Box(
            modifier = Modifier
                .padding(2.dp)
                .clip(CircleShape)
                .background(color)
                .size(16.dp)
        )
    }
}

Pager mit einem Kreissymbol unter dem Inhalt
Abbildung 3: Pager mit einem Kreissymbol unter dem Inhalt

Scrolleffekte von Elementen auf Inhalte anwenden

Ein häufiger Anwendungsfall ist die Verwendung der Scrollposition, um Effekte auf Ihren Pager anzuwenden. Elemente. Um herauszufinden, wie weit eine Seite von der aktuell ausgewählten Seite entfernt ist, können Sie nutzen PagerState.currentPageOffsetFraction Anschließend können Sie Transformationseffekte basierend auf der Entfernung auf Ihre Inhalte anwenden. von der ausgewählten Seite aus.

Abbildung 4: Transformationen auf Pager-Inhalte anwenden

Wenn Sie beispielsweise die Deckkraft von Elementen abhängig davon anpassen möchten, wie weit sie vom ändern Sie den alpha mit Modifier.graphicsLayer für ein Element innerhalb des Pagers:

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(state = pagerState) { page ->
    Card(
        Modifier
            .size(200.dp)
            .graphicsLayer {
                // Calculate the absolute offset for the current page from the
                // scroll position. We use the absolute value which allows us to mirror
                // any effects for both directions
                val pageOffset = (
                    (pagerState.currentPage - page) + pagerState
                        .currentPageOffsetFraction
                    ).absoluteValue

                // We animate the alpha, between 50% and 100%
                alpha = lerp(
                    start = 0.5f,
                    stop = 1f,
                    fraction = 1f - pageOffset.coerceIn(0f, 1f)
                )
            }
    ) {
        // Card content
    }
}

Benutzerdefinierte Seitengrößen

Standardmäßig nehmen HorizontalPager und VerticalPager die volle Breite oder volle Höhe erreicht. Sie können die Variable pageSize so festlegen, dass sie entweder Fixed, Fill (Standard) oder eine benutzerdefinierte Größenberechnung.

So legen Sie beispielsweise eine Seite mit fester Breite von 100.dp fest:

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    pageSize = PageSize.Fixed(100.dp)
) { page ->
    // page content
}

Verwenden Sie eine benutzerdefinierte Seitengröße, um die Größe der Seiten an die Größe des Darstellungsbereichs anzupassen Berechnung. Benutzerdefinierten PageSize und teile availableSpace durch drei, wobei der Abstand berücksichtigt wird zwischen den Elementen:

private val threePagesPerViewport = object : PageSize {
    override fun Density.calculateMainAxisPageSize(
        availableSpace: Int,
        pageSpacing: Int
    ): Int {
        return (availableSpace - 2 * pageSpacing) / 3
    }
}

Abstände im Inhalt

Bei HorizontalPager und VerticalPager kann der Abstand für den Inhalt geändert werden, mit der Sie die maximale Größe und Ausrichtung von Seiten beeinflussen können.

Wenn Sie beispielsweise den Abstand start festlegen, werden die Seiten am Ende ausgerichtet:

Pager mit einem Abstand am Anfang, bei dem der Inhalt am Ende ausgerichtet ist

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    contentPadding = PaddingValues(start = 64.dp),
) { page ->
    // page content
}

Wenn für den Abstand für start und end derselbe Wert festgelegt ist, wird das Element zentriert horizontal:

Pager mit einem Abstand an Anfang und Ende, bei dem der Inhalt in der Mitte angezeigt wird

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    contentPadding = PaddingValues(horizontal = 32.dp),
) { page ->
    // page content
}

Wenn Sie den Abstand end festlegen, werden die Seiten am Anfang ausgerichtet:

Pager mit einem Abstand am Anfang und Ende, bei dem der Inhalt am Anfang ausgerichtet ist

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    contentPadding = PaddingValues(end = 64.dp),
) { page ->
    // page content
}

Sie können die Werte top und bottom festlegen, um ähnliche Effekte für Folgendes zu erzielen: VerticalPager Der Wert 32.dp wird hier nur als Beispiel verwendet. können Sie jede der Abstände auf einen beliebigen Wert.

Scrollverhalten anpassen

Mit den standardmäßigen zusammensetzbaren Funktionen HorizontalPager und VerticalPager wird festgelegt, wie Scrollbewegungen mit dem Pager funktionieren. Sie können sie jedoch anpassen und die Standardwerte wie pagerSnapDistance oder flingBehavior.

Abstand

Standardmäßig legen HorizontalPager und VerticalPager die maximale Anzahl von Seiten, an denen mit nur einer Bewegung bis zu einer Seite nach der anderen gescrollt werden kann. Zum Ändern dies, festlegen pagerSnapDistance am flingBehavior:

val pagerState = rememberPagerState(pageCount = { 10 })

val fling = PagerDefaults.flingBehavior(
    state = pagerState,
    pagerSnapDistance = PagerSnapDistance.atMost(10)
)

Column(modifier = Modifier.fillMaxSize()) {
    HorizontalPager(
        state = pagerState,
        pageSize = PageSize.Fixed(200.dp),
        beyondBoundsPageCount = 10,
        flingBehavior = fling
    ) {
        PagerSampleItem(page = it)
    }
}