للتنقل عبر المحتوى بطريقة لليسار واليمين أو لأعلى ولأسفل، يمكنك استخدام
الـ
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
على قيمة أعلى من صفر.
التمرير إلى عنصر في جهاز النداء
للانتقال إلى صفحة معينة في جهاز النداء، أنشئ
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) ) } }
![جهاز نداء يعرض مؤشر دائرة أسفل المحتوى](https://developer.android.com/static/develop/ui/compose/images/layouts/pager/indicator.png?authuser=1&hl=ar)
تطبيق تأثيرات التمرير على العناصر على المحتوى
من بين حالات الاستخدام الشائعة استخدام موضع التمرير لتطبيق تأثيرات على جهاز النداء
عناصر. لمعرفة مدى بُعد صفحة عن الصفحة المحددة حاليًا، يمكنك
استخدام
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), beyondBoundsPageCount = 10, flingBehavior = fling ) { PagerSampleItem(page = it) } }
أفلام مُقترَحة لك
- ملاحظة: يظهر نص الرابط عند إيقاف JavaScript
- القيود المفروضة في أداة "إنشاء"
- معدِّلات الرسومات
- نقل بيانات
CoordinatorLayout
إلى علامة التبويب "إنشاء"