कॉम्पोनेंट को बाईं और दाईं या ऊपर और नीचे की ओर फ़्लिप करने के लिए, 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
पैरामीटर से यह तय होता है कि कौनसा सर्कल, डार्क ग्रे में रेंडर होगा.
नतीजा
इस वीडियो में, पिछले स्निपेट में दिखाया गया, पेज अपने-आप आगे बढ़ने की सुविधा वाला बुनियादी पेजर दिखाया गया है: