कॉन्टेंट को बाएं से दाएं या ऊपर से नीचे की ओर फ़्लिप करने के लिए, HorizontalPager
और VerticalPager
कंपोज़ेबल का इस्तेमाल किया जा सकता है. इन कंपोज़ेबल के फ़ंक्शन, व्यू सिस्टम में मौजूद ViewPager
के फ़ंक्शन से मिलते-जुलते हैं. डिफ़ॉल्ट रूप से, HorizontalPager
स्क्रीन की पूरी चौड़ाई लेता है, VerticalPager
पूरी ऊंचाई लेता है, और पेजर्स एक बार में सिर्फ़ एक पेज फ़्लिंग करते हैं. इन डिफ़ॉल्ट सेटिंग को कॉन्फ़िगर किया जा सकता है.
HorizontalPager
बाईं और दाईं ओर स्क्रोल करने वाला पेजर बनाने के लिए, HorizontalPager
का इस्तेमाल करें:
HorizontalPager
का डेमो
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
VerticalPager
ऊपर और नीचे की ओर स्क्रोल करने वाला पेजर बनाने के लिए, VerticalPager
का इस्तेमाल करें:
VerticalPager
का डेमो
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
आसानी से कॉन्टेंट बनाना
HorizontalPager
और VerticalPager
, दोनों में मौजूद पेजों को ज़रूरत के मुताबिक लेज़ी कंपोज़िशन और लेआउट किया जाता है. उपयोगकर्ता के पेजों को स्क्रोल करने पर, कंपोज़ेबल उन पेजों को हटा देता है जिनकी अब ज़रूरत नहीं है.
स्क्रीन पर न दिखने वाले ज़्यादा पेज लोड करें
डिफ़ॉल्ट रूप से, पेजर सिर्फ़ स्क्रीन पर दिखने वाले पेजों को लोड करता है. स्क्रीन से बाहर मौजूद ज़्यादा पेजों को लोड करने के लिए, beyondBoundsPageCount
को शून्य से ज़्यादा पर सेट करें.
पेजर में किसी आइटम पर स्क्रोल करना
पेजर में किसी पेज पर स्क्रोल करने के लिए, rememberPagerState()
का इस्तेमाल करके PagerState
ऑब्जेक्ट बनाएं. इसके बाद, इसे पेजर में state
पैरामीटर के तौर पर पास करें. इस स्थिति में, CoroutineScope
के अंदर PagerState#scrollToPage()
को कॉल किया जा सकता है:
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") }
अगर आपको पेज को ऐनिमेट करना है, तो
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") }
पेज की स्थिति में बदलाव होने पर सूचना पाना
PagerState
में पेजों के बारे में जानकारी देने वाली तीन प्रॉपर्टी होती हैं:
currentPage
,
settledPage
,
और
targetPage
.
currentPage
: स्नैप की गई जगह के सबसे नज़दीक वाला पेज. डिफ़ॉल्ट रूप से, स्नैप पोजीशन लेआउट की शुरुआत में होती है.settledPage
: जब कोई ऐनिमेशन या स्क्रोलिंग नहीं चल रही हो, तब पेज नंबर. यहcurrentPage
प्रॉपर्टी से अलग है. ऐसा इसलिए, क्योंकि अगर पेज स्नैप पोज़िशन के काफ़ी करीब है, तोcurrentPage
तुरंत अपडेट हो जाता है. हालांकि,settledPage
तब तक एक जैसा रहता है, जब तक सभी ऐनिमेशन चलना बंद नहीं हो जाते.targetPage
: स्क्रोलिंग के लिए सुझाई गई स्टॉप पोज़िशन.
इन वैरिएबल में हुए बदलावों को देखने और उन पर प्रतिक्रिया देने के लिए, snapshotFlow
फ़ंक्शन का इस्तेमाल किया जा सकता है. उदाहरण के लिए, हर पेज बदलने पर कोई Analytics इवेंट भेजने के लिए,
यह तरीका अपनाया जा सकता है:
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") }
पेज इंडिकेटर जोड़ना
किसी पेज में इंडिकेटर जोड़ने के लिए, PagerState
ऑब्जेक्ट का इस्तेमाल करें. इससे आपको यह जानकारी मिलेगी कि कई पेजों में से कौनसा पेज चुना गया है. साथ ही, इससे आपको अपना कस्टम इंडिकेटर बनाने में मदद मिलेगी.
उदाहरण के लिए, अगर आपको एक सामान्य सर्कल इंडिकेटर चाहिए, तो सर्कल की संख्या को दोहराया जा सकता है. साथ ही, पेज के चुने जाने के आधार पर सर्कल का रंग बदला जा सकता है. इसके लिए, 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) ) } }

कॉन्टेंट पर आइटम स्क्रोल इफ़ेक्ट लागू करना
इसका इस्तेमाल आम तौर पर, स्क्रोल की पोज़िशन के हिसाब से पेजर आइटम पर इफ़ेक्ट लागू करने के लिए किया जाता है. चुने गए मौजूदा पेज से कोई पेज कितनी दूर है, यह जानने के लिए PagerState.currentPageOffsetFraction
का इस्तेमाल किया जा सकता है.
इसके बाद, चुने गए पेज से दूरी के आधार पर, अपने कॉन्टेंट पर ट्रांसफ़ॉर्मेशन इफ़ेक्ट लागू किए जा सकते हैं.
उदाहरण के लिए, आइटम की ओपैसिटी को इस आधार पर अडजस्ट करने के लिए कि वे सेंटर से कितनी दूर हैं, पेजर में मौजूद किसी आइटम पर Modifier.graphicsLayer
का इस्तेमाल करके alpha
को बदलें:
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 } }
पसंद के मुताबिक पेज के साइज़
डिफ़ॉल्ट रूप से, HorizontalPager
और VerticalPager
पूरी चौड़ाई या पूरी ऊंचाई लेते हैं. pageSize
वैरिएबल को Fixed
, Fill
(डिफ़ॉल्ट) या कस्टम साइज़ कैलकुलेशन पर सेट किया जा सकता है.
उदाहरण के लिए, 100.dp
की तय चौड़ाई वाला पेज सेट करने के लिए:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
व्यूपोर्ट के साइज़ के आधार पर पेजों का साइज़ तय करने के लिए, पेज के साइज़ का हिसाब लगाने का कस्टम तरीका इस्तेमाल करें. कस्टम PageSize
ऑब्जेक्ट बनाएं और आइटम के बीच की दूरी को ध्यान में रखते हुए, availableSpace
को तीन हिस्सों में बांटें:
private val threePagesPerViewport = object : PageSize { override fun Density.calculateMainAxisPageSize( availableSpace: Int, pageSpacing: Int ): Int { return (availableSpace - 2 * pageSpacing) / 3 } }
कॉन्टेंट पैडिंग
HorizontalPager
और VerticalPager
, दोनों में कॉन्टेंट पैडिंग बदलने की सुविधा होती है. इससे पेजों के ज़्यादा से ज़्यादा साइज़ और अलाइनमेंट पर असर डाला जा सकता है.
उदाहरण के लिए, start
पैडिंग सेट करने से, पेज आखिर की ओर अलाइन हो जाते हैं:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
start
और end
, दोनों के लिए एक जैसी पैडिंग सेट करने से आइटम, हॉरिज़ॉन्टल तौर पर बीच में आ जाता है:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
end
पैडिंग सेट करने से, पेज शुरुआत की ओर अलाइन हो जाते हैं:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { page -> // page content }
VerticalPager
के लिए एक जैसे इफ़ेक्ट पाने के लिए, top
और bottom
वैल्यू सेट की जा सकती हैं. यहां 32.dp
वैल्यू का इस्तेमाल सिर्फ़ उदाहरण के तौर पर किया गया है. पैडिंग के हर डाइमेंशन के लिए कोई भी वैल्यू सेट की जा सकती है.
स्क्रोल करने के तरीके को पसंद के मुताबिक बनाना
डिफ़ॉल्ट HorizontalPager
और VerticalPager
कंपोज़ेबल से यह तय होता है कि स्क्रोल करने के जेस्चर, पेजर के साथ कैसे काम करते हैं. हालांकि, आपके पास डिफ़ॉल्ट सेटिंग को अपनी पसंद के मुताबिक बनाने और बदलने का विकल्प होता है. जैसे, pagerSnapDistance
या flingBehavior
.
स्नैप की दूरी
डिफ़ॉल्ट रूप से, HorizontalPager
और VerticalPager
, फ़्लिंग जेस्चर से एक बार में स्क्रोल किए जा सकने वाले पेजों की ज़्यादा से ज़्यादा संख्या को एक पेज पर सेट करते हैं. इसे बदलने के लिए, flingBehavior
पर pagerSnapDistance
सेट करें:
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), beyondViewportPageCount = 10, flingBehavior = fling ) { PagerSampleItem(page = it) } }
अपने-आप आगे बढ़ने वाला पेजर बनाना
इस सेक्शन में, Compose में पेज इंडिकेटर के साथ अपने-आप आगे बढ़ने वाला पेज व्यू बनाने का तरीका बताया गया है. आइटम का कलेक्शन, हॉरिज़ॉन्टल तौर पर अपने-आप स्क्रोल होता है. हालांकि, उपयोगकर्ता आइटम के बीच मैन्युअल तरीके से भी स्वाइप कर सकते हैं. अगर कोई उपयोगकर्ता पेजर से इंटरैक्ट करता है, तो यह अपने-आप आगे बढ़ने की सुविधा को बंद कर देता है.
सामान्य उदाहरण
नीचे दिए गए स्निपेट, एक साथ मिलकर ऑटो-ऐडवांसिंग पेजर को लागू करने का एक बुनियादी तरीका बनाते हैं. इसमें विज़ुअल इंडिकेटर भी शामिल होता है. इसमें हर पेज अलग-अलग रंग में रेंडर होता है:
@Composable fun AutoAdvancePager(pageItems: List<Color>, modifier: Modifier = Modifier) { Box(modifier = Modifier.fillMaxSize()) { val pagerState = rememberPagerState(pageCount = { pageItems.size }) val pagerIsDragged by pagerState.interactionSource.collectIsDraggedAsState() val pageInteractionSource = remember { MutableInteractionSource() } val pageIsPressed by pageInteractionSource.collectIsPressedAsState() // Stop auto-advancing when pager is dragged or one of the pages is pressed val autoAdvance = !pagerIsDragged && !pageIsPressed if (autoAdvance) { LaunchedEffect(pagerState, pageInteractionSource) { while (true) { delay(2000) val nextPage = (pagerState.currentPage + 1) % pageItems.size pagerState.animateScrollToPage(nextPage) } } } HorizontalPager( state = pagerState ) { page -> Text( text = "Page: $page", textAlign = TextAlign.Center, modifier = modifier .fillMaxSize() .background(pageItems[page]) .clickable( interactionSource = pageInteractionSource, indication = LocalIndication.current ) { // Handle page click } .wrapContentSize(align = Alignment.Center) ) } PagerIndicator(pageItems.size, pagerState.currentPage) } }
कोड के बारे में अहम जानकारी
AutoAdvancePager
फ़ंक्शन, हॉरिज़ॉन्टल पेजिंग व्यू बनाता है. इसमें पेज अपने-आप आगे बढ़ता है. यहColor
ऑब्जेक्ट की सूची को इनपुट के तौर पर लेता है. इनका इस्तेमाल हर पेज के बैकग्राउंड कलर के तौर पर किया जाता है.pagerState
कोrememberPagerState
का इस्तेमाल करके बनाया जाता है. यह पेजर की स्थिति को सेव करता है.pagerIsDragged
औरpageIsPressed
कुकी, उपयोगकर्ता के इंटरैक्शन को ट्रैक करती हैं.LaunchedEffect
हर दो सेकंड में पेजर को अपने-आप आगे बढ़ाता है. हालांकि, ऐसा तब तक होता है, जब तक उपयोगकर्ता पेजर को खींचकर न ले जाए या किसी पेज को न दबाए.HorizontalPager
में पेजों की सूची दिखती है. हर पेज मेंText
कंपोज़ेबल होता है, जिसमें पेज नंबर दिखता है. मॉडिफ़ायर, पेज को भरता है. साथ ही,pageItems
से बैकग्राउंड का रंग सेट करता है और पेज को क्लिक करने लायक बनाता है.
@Composable fun PagerIndicator(pageCount: Int, currentPageIndex: Int, modifier: Modifier = Modifier) { Box(modifier = Modifier.fillMaxSize()) { Row( modifier = Modifier .wrapContentHeight() .fillMaxWidth() .align(Alignment.BottomCenter) .padding(bottom = 8.dp), horizontalArrangement = Arrangement.Center ) { repeat(pageCount) { iteration -> val color = if (currentPageIndex == iteration) Color.DarkGray else Color.LightGray Box( modifier = modifier .padding(2.dp) .clip(CircleShape) .background(color) .size(16.dp) ) } } } }
कोड के बारे में अहम जानकारी
- रूट एलिमेंट के तौर पर,
Box
कंपोज़ेबल का इस्तेमाल किया जाता है.Box
के अंदर,Row
कंपोज़ेबल, पेज इंडिकेटर को हॉरिजॉन्टल तरीके से व्यवस्थित करता है.
- कस्टम पेज इंडिकेटर को सर्कल की एक लाइन के तौर पर दिखाया जाता है. इसमें हर
Box
क्लिप किए गएcircle
का मतलब एक पेज होता है. - मौजूदा पेज के सर्कल को
DarkGray
के तौर पर रंगा गया है, जबकि अन्य सर्कलLightGray
हैं.currentPageIndex
पैरामीटर से यह तय होता है कि कौनसी सर्कल गहरे स्लेटी रंग में रेंडर होगी.
नतीजा
इस वीडियो में, पिछले स्निपेट से मिले बुनियादी ऑटो-ऐडवांसिंग पेजर को दिखाया गया है: