معدِّلات التمرير
يوفّر المعدّلان
verticalScroll
و
horizontalScroll
أبسط طريقة للسماح للمستخدم بتمرير عنصر عندما تكون حدود محتواه أكبر من قيود الحجم الأقصى. باستخدام المعدِّلَين verticalScroll وhorizontalScroll، لن تحتاج إلى ترجمة المحتوى أو إزاحته.
@Composable private fun ScrollBoxes() { Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .verticalScroll(rememberScrollState()) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
تتيح لك السمة ScrollState
تغيير موضع التمرير أو الحصول على حالته الحالية. لإنشائه
باستخدام المَعلمات التلقائية، استخدِم
rememberScrollState().
@Composable private fun ScrollBoxesSmooth() { // Smoothly scroll 100px on first composition val state = rememberScrollState() LaunchedEffect(Unit) { state.animateScrollTo(100) } Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .padding(horizontal = 8.dp) .verticalScroll(state) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
معدِّل المنطقة القابلة للتمرير
المعدِّل scrollableArea هو وحدة أساسية لإنشاء حاويات مخصّصة قابلة للتمرير. توفّر هذه السمة مستوى تجريد أعلى من المعدِّل
scrollable، وتتعامل مع المتطلبات الشائعة، مثل تفسير الفرق بين الإيماءات، واقتصاص المحتوى، وتأثيرات التمرير الزائد.
على الرغم من أنّ scrollableArea تُستخدَم في عمليات التنفيذ المخصّصة، ننصحك عمومًا باستخدام حلول جاهزة، مثل verticalScroll أو horizontalScroll، أو عناصر قابلة للإنشاء، مثل LazyColumn، لقوائم التمرير العادية. تكون هذه المكوّنات ذات المستوى الأعلى أبسط لحالات الاستخدام الشائعة، وهي نفسها مبنية باستخدام scrollableArea.
الفرق بين المعدِّلَين scrollableArea وscrollable
يكمن الاختلاف الرئيسي بين scrollableArea وscrollable في طريقة تفسيرهما لإيماءات التمرير التي يجريها المستخدم:
scrollable(الفرق الأولي): يعكس الفرق مباشرةً الحركة الفعلية التي أجراها المستخدم (مثل سحب المؤشر) على الشاشة.scrollableArea(دلتا موجّهة نحو المحتوى): يتم عكسdeltaدلاليًا لتمثيل التغيير المحدّد في موضع التمرير لجعل المحتوى يبدو وكأنّه يتحرّك مع إيماءة المستخدم، وهو ما يكون عادةً عكس حركة المؤشر.
يمكنك التفكير في الأمر على النحو التالي: يخبرك scrollable بكيفية تحرّك المؤشر، بينما يحوّل scrollableArea حركة المؤشر هذه إلى كيفية تحرّك المحتوى ضمن طريقة العرض العادية القابلة للتمرير. هذا الانعكاس هو السبب في أنّ scrollableArea
يبدو أكثر طبيعية عند تنفيذ حاوية عادية قابلة للتمرير.
يلخّص الجدول التالي إشارات التغيير في السيناريوهات الشائعة:
إيماءة المستخدم |
تم إرسال تقرير عن السلالة المتحوّرة دلتا إلى |
تم إرسال قيمة التغيير إلى |
|---|---|---|
تحرُّك المؤشر للأعلى |
سلبية |
إيجابي |
تحرُّك المؤشر للأسفل |
إيجابي |
سلبية |
تحرُّك المؤشر لليسار |
سلبية |
إيجابي (سلبي للغات من اليمين إلى اليسار) |
تحرُّك المؤشر لليسار |
إيجابي |
سالب (موجب للغات من اليمين إلى اليسار) |
(*) ملاحظة حول scrollableArea علامة دلتا: إنّ علامة دلتا من
scrollableArea ليست مجرد انعكاس بسيط. تأخذ هذه الميزة في الاعتبار بذكاء ما يلي:
- الاتجاه: عمودي أو أفقي
LayoutDirection: من اليمين إلى اليسار أو من اليسار إلى اليمين (مهم بشكل خاص للتمرير الأفقي).- علامة
reverseScrolling: لتحديد ما إذا كان اتجاه التمرير معكوسًا.
بالإضافة إلى عكس الفرق في التمرير، تعمل السمة scrollableArea أيضًا على قص المحتوى ضمن حدود التصميم ومعالجة تأثيرات التمرير الزائد. يستخدم هذا الخيار تلقائيًا التأثير الذي توفّره LocalOverscrollFactory.
يمكنك تخصيص هذا السلوك أو إيقافه باستخدام التحميل الزائد scrollableArea الذي يقبل المَعلمة OverscrollEffect.
حالات استخدام المعدِّل scrollableArea
يجب استخدام المعدِّل scrollableArea عندما تحتاج إلى إنشاء مكوّن مخصّص للتمرير لا يمكن توفيره بشكل كافٍ من خلال المعدِّلين horizontalScroll أو verticalScroll أو التصاميم الكسولة. يشمل ذلك غالبًا الحالات التي تتضمّن ما يلي:
- منطق التنسيق المخصّص: عندما يتغيّر ترتيب العناصر بشكل ديناميكي استنادًا إلى موضع التمرير
- تأثيرات بصرية فريدة: تطبيق عمليات تحويل أو تغيير حجم أو تأثيرات أخرى على الأطفال أثناء التمرير
- التحكّم المباشر: الحاجة إلى تحكّم دقيق في آليات التمرير
بما يتجاوز ما تعرضه
verticalScrollأو التنسيقات الكسولة
إنشاء قوائم مخصّصة على شكل عجلة باستخدام scrollableArea
يوضّح المثال التالي كيفية استخدام scrollableArea لإنشاء قائمة عمودية مخصّصة يتم فيها تصغير حجم العناصر كلما ابتعدت عن المنتصف، ما يؤدي إلى إنشاء تأثير مرئي "شبيه بالعجلة". هذا النوع من عمليات التحويل المستندة إلى التمرير هو حالة استخدام مثالية لـ scrollableArea.
scrollableArea
@Composable private fun ScrollableAreaSample() { // ... Layout( modifier = Modifier .size(150.dp) .scrollableArea(scrollState, Orientation.Vertical) .background(Color.LightGray), // ... ) { measurables, constraints -> // ... // Update the maximum scroll value to not scroll beyond limits and stop when scroll // reaches the end. scrollState.maxValue = (totalHeight - viewportHeight).coerceAtLeast(0) // Position the children within the layout. layout(constraints.maxWidth, viewportHeight) { // The current vertical scroll position, in pixels. val scrollY = scrollState.value val viewportCenterY = scrollY + viewportHeight / 2 var placeableLayoutPositionY = 0 placeables.forEach { placeable -> // This sample applies a scaling effect to items based on their distance // from the center, creating a wheel-like effect. // ... // Place the item horizontally centered with a layer transformation for // scaling to achieve wheel-like effect. placeable.placeRelativeWithLayer( x = constraints.maxWidth / 2 - placeable.width / 2, // Offset y by the scroll position to make placeable visible in the viewport. y = placeableLayoutPositionY - scrollY, ) { scaleX = scaleFactor scaleY = scaleFactor } // Move to the next item's vertical position. placeableLayoutPositionY += placeable.height } } } } // ...
عنصر تعديل قابل للتمرير
المقاطع محتواها ضمن حدودها، وتعرض التمرير الزائد، وتعدّل اتجاه إيماءات التمرير للتحقّق من أنّ المحتوى يتحرّك مع إيماءات المستخدم.يختلف المعدِّل
scrollable
عن معدِّلات التمرير في أنّ scrollable يرصد إيماءات التمرير ويلتقط القيم المتغيرة، لكنّه لا يزيح محتواه تلقائيًا. بدلاً من ذلك، يتم تفويض هذا الإذن إلى المستخدم من خلال
ScrollableState
، وهو أمر ضروري لكي يعمل معدِّل الوصول هذا بشكل صحيح.
عند إنشاء ScrollableState، يجب توفير دالة consumeScrollDelta سيتم استدعاؤها في كل خطوة من خطوات التمرير (من خلال إدخال الإيماءات أو التمرير السلس أو التمرير السريع) مع الفرق بالبكسل. يجب أن تعرض هذه الدالة مقدار مسافة التمرير التي تم استهلاكها، وذلك لضمان نشر الحدث بشكل صحيح في الحالات التي تتضمّن عناصر متداخلة تحتوي على المعدِّل scrollable.
تعمل المقتطفة البرمجية التالية على رصد الإيماءات وعرض قيمة رقمية للإزاحة، ولكنّها لا تعمل على إزاحة أي عناصر:
@Composable private fun ScrollableSample() { // actual composable state var offset by remember { mutableFloatStateOf(0f) } Box( Modifier .size(150.dp) .scrollable( orientation = Orientation.Vertical, // Scrollable state: describes how to consume // scrolling delta and update offset state = rememberScrollableState { delta -> offset += delta delta } ) .background(Color.LightGray), contentAlignment = Alignment.Center ) { Text(offset.toString()) } }
مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما تكون JavaScript غير مفعّلة.
- التعرّف على الإيماءات
- نقل البيانات من
CoordinatorLayoutإلى Compose - استخدام طرق العرض في Compose