FlowRow
وFlowColumn
هما عنصران قابلان للإنشاء يشبهان Row
وColumn
، ولكن يختلفان في أنّ العناصر
تنتقل إلى السطر التالي عندما تنفد المساحة في الحاوية. سيؤدي ذلك إلى إنشاء
صفوف أو أعمدة متعددة. يمكن أيضًا التحكّم في عدد العناصر في سطر واحد من خلال ضبط maxItemsInEachRow
أو maxItemsInEachColumn
. يمكنك غالبًا استخدام
FlowRow
وFlowColumn
لإنشاء تنسيقات متجاوبة، فلن يتم اقتطاع المحتوى إذا كانت العناصر كبيرة جدًا بالنسبة إلى أحد الأبعاد، ويمكن أن يساعد استخدام مجموعة من
maxItemsInEach*
مع Modifier.weight(weight)
في إنشاء تنسيقات
تعبئة/توسيع عرض صف أو عمود عند الحاجة.
المثال النموذجي هو واجهة مستخدم لفلتر أو شريحة:

FlowRow
الاستخدام الأساسي
لاستخدام 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 عناصر فقط:
لم يتم ضبط حد أقصى |
|
![]() |
![]() |
أوزان السلع
يزيد الوزن حجم العنصر استنادًا إلى عامله والمساحة المتوفّرة في السطر الذي تم وضعه فيه. من المهم معرفة أنّ هناك فرقًا بين FlowRow
وRow
في طريقة استخدام الأوزان لحساب عرض عنصر. بالنسبة إلى Rows
، يستند الوزن إلى جميع العناصر في Row
. باستخدام FlowRow
، يستند الوزن إلى
العناصر في السطر الذي يتم وضع العنصر فيه، وليس إلى جميع العناصر في حاوية FlowRow
.
على سبيل المثال، إذا كان لديك 4 عناصر تقع جميعها على خط واحد، ولكل منها أوزان مختلفة تبلغ 1f, 2f, 1f
و3f
، سيكون الوزن الإجمالي 7f
. سيتم تقسيم المساحة المتبقية
في صف أو عمود على 7f
. بعد ذلك، سيتم احتساب عرض كل عنصر باستخدام: weight * (remainingSpace / totalWeight)
.
يمكنك استخدام مجموعة من Modifier.weight
والحد الأقصى للعناصر مع FlowRow
أو FlowColumn
لإنشاء تخطيط شبكي. ويفيد هذا الأسلوب في إنشاء تصميمات متجاوبة تتكيّف مع حجم جهازك.
في ما يلي بعض الأمثلة المختلفة على ما يمكنك تحقيقه باستخدام الأوزان. أحد الأمثلة على ذلك هو شبكة تكون فيها العناصر متساوية الحجم، كما هو موضّح أدناه:

FlowRow
لإنشاء شبكةلإنشاء شبكة بأحجام عناصر متساوية، يمكنك اتّباع الخطوات التالية:
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
:

FlowRow
لإنشاء شبكة مع احتلال العنصر الأخير للعرض الكامليمكنك دمج الأوزان مع Modifiers
أخرى، مثل
Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
أو
Modifier.fillMaxWidth(fraction)
. تعمل كل هذه المعدّلات معًا
للسماح بتحديد حجم العناصر بشكل متجاوب ضمن FlowRow
(أو FlowColumn
).
يمكنك أيضًا إنشاء شبكة متناوبة بأحجام عناصر مختلفة، حيث يشغل عنصران نصف العرض لكل منهما، ويشغل عنصر واحد العرض الكامل للعمود التالي:

FlowRow
مع أحجام متناوبة للصفوفيمكنك تحقيق ذلك باستخدام الرمز التالي:
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 في Compose
- إجراءات المحرّر {:#editor-actions}