@@ -20,7 +20,12 @@ package com.example.compose.snippets.layouts
20
20
21
21
import android.util.Log
22
22
import androidx.compose.foundation.Image
23
+ import androidx.compose.foundation.LocalIndication
23
24
import 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
24
29
import androidx.compose.foundation.layout.Arrangement
25
30
import androidx.compose.foundation.layout.Box
26
31
import androidx.compose.foundation.layout.Column
@@ -50,6 +55,8 @@ import androidx.compose.material3.TabRow
50
55
import androidx.compose.material3.Text
51
56
import androidx.compose.runtime.Composable
52
57
import androidx.compose.runtime.LaunchedEffect
58
+ import androidx.compose.runtime.getValue
59
+ import androidx.compose.runtime.remember
53
60
import androidx.compose.runtime.rememberCoroutineScope
54
61
import androidx.compose.runtime.snapshotFlow
55
62
import androidx.compose.ui.Alignment
@@ -58,13 +65,15 @@ import androidx.compose.ui.draw.clip
58
65
import androidx.compose.ui.graphics.Color
59
66
import androidx.compose.ui.graphics.graphicsLayer
60
67
import androidx.compose.ui.layout.ContentScale
68
+ import androidx.compose.ui.text.style.TextAlign
61
69
import androidx.compose.ui.tooling.preview.Preview
62
70
import androidx.compose.ui.unit.Density
63
71
import androidx.compose.ui.unit.dp
64
72
import androidx.compose.ui.util.lerp
65
73
import coil.compose.rememberAsyncImagePainter
66
74
import com.example.compose.snippets.util.rememberRandomSampleImageUrl
67
75
import kotlin.math.absoluteValue
76
+ import kotlinx.coroutines.delay
68
77
import kotlinx.coroutines.launch
69
78
70
79
/*
@@ -83,6 +92,18 @@ import kotlinx.coroutines.launch
83
92
* limitations under the License.
84
93
*/
85
94
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
+
86
107
@Preview
87
108
@Composable
88
109
fun HorizontalPagerSample () {
@@ -392,6 +413,94 @@ fun PagerIndicator() {
392
413
}
393
414
}
394
415
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
+
395
504
// [START android_compose_pager_custom_page_size]
396
505
private val threePagesPerViewport = object : PageSize {
397
506
override fun Density.calculateMainAxisPageSize (
0 commit comments