כדי לדפדף בתוכן שמאלה או ימינה או למעלה או למטה, אפשר להשתמש ברכיבי ה-Composable HorizontalPager
ו-VerticalPager
, בהתאמה. לרכיבים האלה יש פונקציות דומות לViewPager
במערכת התצוגות. כברירת מחדל, HorizontalPager
תופס את כל רוחב המסך, VerticalPager
תופס את כל הגובה והמכשירים להעברת דפים מעבירים רק דף אחד בכל פעם. את כל ברירות המחדל האלה אפשר לקבוע.
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
:
// 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
לערך שגבוה מאפס.
גלילה לפריט בחלונית הגלילה
כדי לגלול לדף מסוים באיתורית, יוצרים אובייקט PagerState
באמצעות rememberPagerState()
ומעבירים אותו כפרמטר state
לזימונית. אפשר להפעיל את הפונקציה PagerState#scrollToPage()
במצב הזה, בתוך 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") }
אם רוצים להוסיף אנימציה לדף, משתמשים בפונקציה 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
.
לאחר מכן תוכלו להחיל על התוכן אפקטים של טרנספורמציה על סמך המרחק מהדף שנבחר.
לדוגמה, כדי לשנות את השקיפות של פריטים בהתאם למרחק שלהם מהמרכז, משנים את הערך של alpha
באמצעות Modifier.graphicsLayer
בפריט בתוך החלונית לדפדוף:
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 }
אפשר להגדיר את הערכים top
ו-bottom
כדי להשיג אפקטים דומים בשביל VerticalPager
. הערך 32.dp
משמש כאן רק כדוגמה. אפשר להגדיר לכל אחד ממאפייני המילוי ערך כלשהו.
התאמה אישית של התנהגות הגלילה
התכנים הקומפוזביליים HorizontalPager
ו-VerticalPager
שמוגדרים כברירת מחדל מציינים איך תנועות הגלילה פועלות עם הזימונית. אבל אפשר להתאים אישית את ברירות המחדל ולשנות אותן, כמו pagerSnapDistance
או flingBehavior
.
מרחק כיווץ
כברירת מחדל, HorizontalPager
ו-VerticalPager
מגדירים את המספר המקסימלי של דפים שאפשר לגלול דרכם בתנועת זריקה לדף אחד בכל פעם. כדי לשנות את זה, צריך להגדיר את pagerSnapDistance
ב-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), beyondViewportPageCount = 10, flingBehavior = fling ) { PagerSampleItem(page = it) } }
מומלץ עבורך
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- ConstraintLayout ב-Compose
- מפעילי גרפיקה
- העברת
CoordinatorLayout
ל-Compose