@@ -20,7 +20,12 @@ package com.example.compose.snippets.layouts
2020
2121import android.util.Log
2222import androidx.compose.foundation.Image
23+ import androidx.compose.foundation.LocalIndication
2324import androidx.compose.foundation.background
25+ import androidx.compose.foundation.clickable
26+ import androidx.compose.foundation.interaction.MutableInteractionSource
27+ import androidx.compose.foundation.interaction.collectIsDraggedAsState
28+ import androidx.compose.foundation.interaction.collectIsPressedAsState
2429import androidx.compose.foundation.layout.Arrangement
2530import androidx.compose.foundation.layout.Box
2631import androidx.compose.foundation.layout.Column
@@ -50,6 +55,8 @@ import androidx.compose.material3.TabRow
5055import androidx.compose.material3.Text
5156import androidx.compose.runtime.Composable
5257import androidx.compose.runtime.LaunchedEffect
58+ import androidx.compose.runtime.getValue
59+ import androidx.compose.runtime.remember
5360import androidx.compose.runtime.rememberCoroutineScope
5461import androidx.compose.runtime.snapshotFlow
5562import androidx.compose.ui.Alignment
@@ -58,14 +65,16 @@ import androidx.compose.ui.draw.clip
5865import androidx.compose.ui.graphics.Color
5966import androidx.compose.ui.graphics.graphicsLayer
6067import androidx.compose.ui.layout.ContentScale
68+ import androidx.compose.ui.text.style.TextAlign
6169import androidx.compose.ui.tooling.preview.Preview
6270import androidx.compose.ui.unit.Density
6371import androidx.compose.ui.unit.dp
6472import androidx.compose.ui.util.lerp
6573import coil.compose.rememberAsyncImagePainter
6674import com.example.compose.snippets.util.rememberRandomSampleImageUrl
67- import kotlin.math.absoluteValue
75+ import kotlinx.coroutines.delay
6876import kotlinx.coroutines.launch
77+ import kotlin.math.absoluteValue
6978
7079/*
7180* Copyright 2023 The Android Open Source Project
@@ -83,6 +92,18 @@ import kotlinx.coroutines.launch
8392* limitations under the License.
8493*/
8594
95+ @Composable
96+ fun PagerExamples (){
97+ AutoAdvancePager (
98+ listOf (
99+ Color .Red ,
100+ Color .Gray ,
101+ Color .Green ,
102+ Color .White
103+ )
104+ )
105+ }
106+
86107@Preview
87108@Composable
88109fun HorizontalPagerSample () {
@@ -256,9 +277,9 @@ fun PagerWithEffect() {
256277 // scroll position. We use the absolute value which allows us to mirror
257278 // any effects for both directions
258279 val pageOffset = (
259- (pagerState.currentPage - page) + pagerState
260- .currentPageOffsetFraction
261- ).absoluteValue
280+ (pagerState.currentPage - page) + pagerState
281+ .currentPageOffsetFraction
282+ ).absoluteValue
262283
263284 // We animate the alpha, between 50% and 100%
264285 alpha = lerp(
@@ -392,6 +413,94 @@ fun PagerIndicator() {
392413 }
393414}
394415
416+ @Composable
417+ fun AutoAdvancePager (pageItems : List <Color >, modifier : Modifier = Modifier ) {
418+ Box (modifier = Modifier .fillMaxSize()) {
419+ val pagerState = rememberPagerState(pageCount = { pageItems.size })
420+ val pagerIsDragged by pagerState.interactionSource.collectIsDraggedAsState()
421+
422+ val pageInteractionSource = remember { MutableInteractionSource () }
423+ val pageIsPressed by pageInteractionSource.collectIsPressedAsState()
424+
425+ // Stop auto-advancing when pager is dragged or one of the pages is pressed
426+ val autoAdvance = ! pagerIsDragged && ! pageIsPressed
427+
428+ if (autoAdvance) {
429+ LaunchedEffect (pagerState, pageInteractionSource) {
430+ while (true ) {
431+ delay(2000 )
432+ val nextPage = (pagerState.currentPage + 1 ) % pageItems.size
433+ pagerState.animateScrollToPage(nextPage)
434+ }
435+ }
436+ }
437+
438+ HorizontalPager (
439+ state = pagerState
440+ ) { page ->
441+ Text (
442+ text = " Page: $page " ,
443+ textAlign = TextAlign .Center ,
444+ modifier = modifier
445+ .fillMaxSize()
446+ .background(pageItems[page])
447+ .clickable(
448+ interactionSource = pageInteractionSource,
449+ indication = LocalIndication .current
450+ ) {
451+ // Handle page click
452+ }
453+ .wrapContentSize(align = Alignment .Center )
454+ )
455+ }
456+
457+ PagerIndicator (pageItems.size, pagerState.currentPage)
458+ }
459+ }
460+
461+ @Preview
462+ @Composable
463+ private fun AutoAdvancePagerPreview () {
464+ val pageItems: List <Color > = listOf (
465+ Color .Red ,
466+ Color .Gray ,
467+ Color .Green ,
468+ Color .White
469+ )
470+ AutoAdvancePager (pageItems = pageItems)
471+ }
472+
473+ @Composable
474+ fun PagerIndicator (pageCount : Int , currentPageIndex : Int , modifier : Modifier = Modifier ) {
475+ Box (modifier = Modifier .fillMaxSize()) {
476+ Row (
477+ modifier = Modifier
478+ .wrapContentHeight()
479+ .fillMaxWidth()
480+ .align(Alignment .BottomCenter )
481+ .padding(bottom = 8 .dp),
482+ horizontalArrangement = Arrangement .Center
483+ ) {
484+ repeat(pageCount) { iteration ->
485+ val color = if (currentPageIndex == iteration) Color .DarkGray else Color .LightGray
486+ Box (
487+ modifier = modifier
488+ .padding(2 .dp)
489+ .clip(CircleShape )
490+ .background(color)
491+ .size(16 .dp)
492+ )
493+ }
494+ }
495+ }
496+ }
497+
498+ @Preview
499+ @Composable
500+ private fun PagerIndicatorPreview () {
501+ PagerIndicator (pageCount = 4 , currentPageIndex = 1 )
502+ }
503+
395504// [START android_compose_pager_custom_page_size]
396505private val threePagesPerViewport = object : PageSize {
397506 override fun Density.calculateMainAxisPageSize (
0 commit comments