FlowRow
وFlowColumn
هما عنصران قابلان للتجميع يشبهان Row
وColumn
، ولكنهما يختلفان في أنّ العناصر
تتدفق إلى السطر التالي عندما تنفد المساحة في الحاوية. يؤدي هذا إلى إنشاء
صفوف أو أعمدة متعددة. يمكن أيضًا التحكّم في عدد العناصر في السطر
من خلال ضبط maxItemsInEachRow
أو maxItemsInEachColumn
. يمكنك غالبًا استخدام
FlowRow
وFlowColumn
لإنشاء تصاميم متجاوبة، ولن يتم اقتطاع المحتوى
إذا كانت العناصر كبيرة جدًا لبُعد واحد، ويمكن أن يساعد استخدام maxItemsInEach*
معModifier.weight(weight)
في إنشاء تصاميم تُملأ/تُوسّع عرض صف أو عمود عند الحاجة.
يتمثل المثال المعتاد في شريحة أو واجهة مستخدم للفلترة:
الاستخدام الأساسي
لاستخدام FlowRow
أو FlowColumn
، أنشئ هذه العناصر القابلة للتجميع ووضِّع العناصر
داخلها التي يجب أن تتّبع المسار العادي:
@Composable private fun FlowRowSimpleUsageExample() { FlowRow(modifier = Modifier.padding(8.dp)) { ChipItem("Price: High to Low") ChipItem("Avg rating: 4+") ChipItem("Free breakfast") ChipItem("Free cancellation") ChipItem("£50 pn") } }
يؤدي هذا المقتطف إلى ظهور واجهة المستخدم الموضّحة أعلاه، مع تدفق العناصر تلقائيًا إلى الصف التالي عندما لا تتوفّر مساحة في الصف الأول.
ميزات تنسيق التدفق
تتضمّن تنسيقات "التنقّل" الميزات والخصائص التالية التي يمكنك استخدامها ل إنشاء تنسيقات مختلفة في تطبيقك.
ترتيب المحور الرئيسي: ترتيب أفقي أو عمودي
المحور الرئيسي هو المحور الذي يتم ترتيب العناصر عليه (على سبيل المثال، في
FlowRow
، يتم ترتيب العناصر أفقيًا). تتحكّم المَعلمة horizontalArrangement
في FlowRow
في طريقة توزيع المساحة الفارغة بين العناصر.
يعرض الجدول التالي أمثلة على ضبط horizontalArrangement
في العناصر للسمة FlowRow
:
تم ضبط الترتيب الأفقي في |
النتيجة |
|
|
بالنسبة إلى FlowColumn
، تتوفّر خيارات مشابهة مع verticalArrangement
، مع
الخيار التلقائي Arrangement.Top
.
ترتيب عبر المحور
المحور العرضي هو المحور في الاتجاه المقابل للمحور الرئيسي. على سبيل المثال، في FlowRow
، يشير ذلك إلى المحور العمودي. لتغيير طريقة ترتيب المحتوى الإجمالي داخل الحاوية على المحور المتقاطع، استخدِم verticalArrangement
لـ FlowRow
وhorizontalArrangement
في FlowColumn
.
بالنسبة إلى FlowRow
، يعرض الجدول التالي أمثلة على ضبط verticalArrangement
مختلفة على العناصر:
تم ضبط الترتيب العمودي في |
النتيجة |
|
|
بالنسبة إلى FlowColumn
، تتوفّر خيارات مشابهة في horizontalArrangement
.
الترتيب التلقائي للمحور المتقاطع هو Arrangement.Start
.
محاذاة العناصر الفردية
قد تحتاج إلى وضع عناصر فردية في الصف باستخدام اتّجاهات مختلفه
للمحاذاة. يختلف هذا عن verticalArrangement
و
horizontalArrangement
لأنّه يُحاذا العناصر داخل السطر الحالي. يمكنك
تطبيق ذلك باستخدام Modifier.align()
.
على سبيل المثال، عندما تكون ارتفاعات العناصر في FlowRow
مختلفة، يأخذ الصف
ارتفاع العنصر الأكبر ويطبّق Modifier.align(alignmentOption)
على
العناصر:
تم ضبط المحاذاة العمودية على |
النتيجة |
|
|
تتوفّر خيارات مشابهة في FlowColumn
. المحاذاة التلقائية هي
Alignment.Start
.
الحد الأقصى للعناصر في الصف أو العمود
تحدّد المَعلمتان maxItemsInEachRow
أو maxItemsInEachColumn
الحد الأقصى
للعناصر في المحور الرئيسي للسماح بها في سطر واحد قبل الانتقال إلى السطر التالي. والقيمة
التلقائية هي Int.MAX_INT
، وهي تسمح بأكبر عدد ممكن من السلع شرط أن
تتناسب مقاساتها مع الخط.
على سبيل المثال، يؤدي ضبط السمة maxItemsInEachRow
إلى فرض تضمين 3 عناصر فقط في التنسيق الأولي، وهي:
لم يتم ضبط حدّ أقصى. |
|
عناصر مسار التحميل الكسول
ContextualFlowRow
وContextualFlowColumn
هما علامتان متخصصتان
لهما FlowRow
وFlowColumn
، تتيحان لك تحميل محتوى الصف أو العمود في العرض بدون تحميله بالكامل. وتوفّر هذه السمات أيضًا معلومات حول موضع العناصر
(الفهرس ورقم الصف والحجم المتاح)، مثل ما إذا كان العنصر في الصف
الأول. يكون ذلك مفيدًا لمجموعات البيانات الكبيرة وإذا كنت بحاجة إلى معلومات سياقية
عن عنصر معيّن.
تحدّد المَعلمة maxLines
عدد الصفوف المعروضة، وتحدِّد المَعلمة overflow
ما يجب عرضه عند الوصول إلى عدد أكبر من العناصر،
ما يسمح لك بتحديد قيمة مخصّصة expandIndicator
أو collapseIndicator
.
على سبيل المثال، لإظهار الزر "+ (عدد العناصر المتبقية)" أو الزر "إظهار عناصر أقل":
val totalCount = 40 var maxLines by remember { mutableStateOf(2) } val moreOrCollapseIndicator = @Composable { scope: ContextualFlowRowOverflowScope -> val remainingItems = totalCount - scope.shownItemCount ChipItem(if (remainingItems == 0) "Less" else "+$remainingItems", onClick = { if (remainingItems == 0) { maxLines = 2 } else { maxLines += 5 } }) } ContextualFlowRow( modifier = Modifier .safeDrawingPadding() .fillMaxWidth(1f) .padding(16.dp) .wrapContentHeight(align = Alignment.Top) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(4.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), maxLines = maxLines, overflow = ContextualFlowRowOverflow.expandOrCollapseIndicator( minRowsToShowCollapse = 4, expandIndicator = moreOrCollapseIndicator, collapseIndicator = moreOrCollapseIndicator ), itemCount = totalCount ) { index -> ChipItem("Item $index") }
أوزان السلع
يزداد الوزن أي عنصر بناءً على عامله والمساحة المتاحة على الخط الذي تم وضعه فيه. من المهم معرفة أنّ هناك فرقًا بين FlowRow
وRow
في كيفية استخدام الأوزان لحساب عرض السلعة. بالنسبة إلى Rows
، يستند الوزن إلى كل العناصر في Row
. في سمة FlowRow
، يستند الوزن إلى
العناصر في الصف الذي يتم وضع العنصر فيه، وليس إلى جميع العناصر في حاوية
FlowRow
.
على سبيل المثال، إذا كان لديك 4 سلع تقع جميعها على خط واحد، ولكل منها كثافة مختلفة تبلغ 1f, 2f, 1f
و3f
، يكون إجمالي الكثافة 7f
. سيتم تقسيم المساحة المتبقية
في صف أو عمود على 7f
. بعد ذلك، سيتم حساب عرض كل عنصر باستخدام: weight * (remainingSpace / totalWeight)
.
يمكنك استخدام مجموعة من Modifier.weight
وعدد العناصر الأقصى مع FlowRow
أو
FlowColumn
لإنشاء تنسيق شبيه بالشبكة. يعد هذا الأسلوب مفيدًا لإنشاء تخطيطات سريعة
استجابة تتكيّف مع حجم جهازك.
في ما يلي بعض الأمثلة المختلفة على ما يمكنك تحقيقه باستخدام الأوزان. أحد الأمثلة على ذلك هو شبكة تكون فيها العناصر بنفس الحجم، كما هو موضح أدناه:
لإنشاء شبكة بأحجام عناصر متساوية، يمكنك القيام بما يلي:
val rows = 3 val columns = 3 FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = rows ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .weight(1f) .clip(RoundedCornerShape(8.dp)) .background(MaterialColors.Blue200) repeat(rows * columns) { Spacer(modifier = itemModifier) } }
المهم، إذا أضفت عنصرًا آخر وكررته 10 مرات بدلاً من 9، فسيشغل العنصر الأخير العمود الأخير بأكمله، حيث يبلغ الوزن الإجمالي للصف بأكمله 1f
:
يمكنك دمج الأوزان مع Modifiers
أخرى، مثل
Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
أو
Modifier.fillMaxWidth(fraction)
. تعمل جميع هذه المُعدِّلات معًا لسماح
بتغيير حجم العناصر داخل FlowRow
(أو FlowColumn
) استجابةً للشاشة.
يمكنك أيضًا إنشاء شبكة بديلة لأحجام عناصر مختلفة، حيث يشغل عنصران نصف عرض كل منهما، ويشغل عنصر واحد عرض العمود التالي بالكامل:
يمكنك تحقيق ذلك باستخدام التعليمة البرمجية التالية:
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 2 ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .clip(RoundedCornerShape(8.dp)) .background(Color.Blue) repeat(6) { item -> // if the item is the third item, don't use weight modifier, but rather fillMaxWidth if ((item + 1) % 3 == 0) { Spacer(modifier = itemModifier.fillMaxWidth()) } else { Spacer(modifier = itemModifier.weight(0.5f)) } } }
التحجيم الجزئي
باستخدام Modifier.fillMaxWidth(fraction)
، يمكنك تحديد حجم
الحاوية التي يجب أن تشغلها السلعة. ويختلف ذلك عن طريقة عمل
Modifier.fillMaxWidth(fraction)
عند تطبيقه على Row
أو Column
، إذ إنّ عناصر Row/Column
تشغل نسبة مئوية من العرض المتبقي، بدلاً من
عرض الحاوية بالكامل.
على سبيل المثال، ينتج عن الرمز البرمجي التالي نتائج مختلفة عند استخدام FlowRow
مقارنةً بـ Row
:
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 3 ) { val itemModifier = Modifier .clip(RoundedCornerShape(8.dp)) Box( modifier = itemModifier .height(200.dp) .width(60.dp) .background(Color.Red) ) Box( modifier = itemModifier .height(200.dp) .fillMaxWidth(0.7f) .background(Color.Blue) ) Box( modifier = itemModifier .height(200.dp) .weight(1f) .background(Color.Magenta) ) }
|
|
|
fillMaxColumnWidth()
وfillMaxRowHeight()
يؤدّي تطبيق Modifier.fillMaxColumnWidth()
أو
Modifier.fillMaxRowHeight()
على عنصر داخل FlowColumn
أو FlowRow
إلى ضمان أن تشغل العناصر في العمود أو الصف نفسه العرض أو الارتفاع نفسه
كأكبر عنصر في العمود/الصف.
على سبيل المثال، يستخدم هذا المثال FlowColumn
لعرض قائمة أطباق Android
حلوى. يمكنك ملاحظة الفرق في عرض كل عنصر عند تطبيقModifier.fillMaxColumnWidth()
على العناصر مقارنةً بعدم تطبيقه و
لف العناصر.
FlowColumn( Modifier .padding(20.dp) .fillMaxHeight() .fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp), maxItemsInEachColumn = 5, ) { repeat(listDesserts.size) { Box( Modifier .fillMaxColumnWidth() .border(1.dp, Color.DarkGray, RoundedCornerShape(8.dp)) .padding(8.dp) ) { Text( text = listDesserts[it], fontSize = 18.sp, modifier = Modifier.padding(3.dp) ) } } }
تم تطبيق |
|
لم يتم ضبط تغييرات العرض (التفاف العناصر) |
أفلام مُقترَحة لك
- ملاحظة: يظهر نص الرابط عند إيقاف JavaScript
- أساسيات تنسيق الرسائل
- ConstraintLayout في أداة "الإنشاء"
- إجراءات المحرِّر {:#editor-actions}