لقلب المحتوى لليسار واليمين أو للأعلى والأسفل، يمكنك استخدام العنصرين التاليين:
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
لمراقبة التغييرات في هذه المتغيّرات
والاستجابة لها. على سبيل المثال، لإرسال حدث إحصاءات عند كل تغيير في الصفحة،
يمكنك إجراء ما يلي:
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 في أداة "الإنشاء"
- مُعدِّلات الرسومات
- نقل
CoordinatorLayout
إلى ميزة "إنشاء"