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}