ضبط خصائص الحاوية

يمكنك تحديد إعدادات حاوية الشبكة لإنشاء تنسيقات مرنة تستجيب لأحجام الشاشات وأنواع المحتوى المختلفة. توضّح هذه الصفحة كيفية إجراء ما يلي:

  • تحديد شبكة: يمكنك إعداد البنية الأساسية للصفوف والأعمدة.
  • وضع العناصر في شبكة: يمكنك التعرّف على كيفية وضع العناصر في خلايا الشبكة وكيفية تغيير اتجاه التدفق.
  • إدارة حجم المسار: يمكنك استخدام أحجام المسارات الثابتة والنسبة المئوية والمرنة والجوهرية لضبط أحجام المسارات.
  • ضبط الفواصل: يمكنك إدارة "المسافات" بين الصفوف والأعمدة.

تحديد شبكة

تتكوّن الشبكة من أعمدة وصفوف. يحتوي العنصر الإنشائي Grid على مَعلمة config تقبل تعبير لامدا لتحديد الأعمدة والصفوف ضمن GridConfigurationScope. يحدّد المثال التالي شبكة تتضمّن ثلاثة صفوف وعمودَين، لكل منهما حجم ثابت محدّد في Dp:

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
    }
) {
}

وضع العناصر في شبكة

يأخذ العنصر الإنشائي Grid عناصر واجهة المستخدم في تعبير لامدا content ويضعها في خلايا الشبكة. تنسّق الشبكة العناصر بغض النظر عمّا إذا كنت قد حدّدت الصفوف والأعمدة بشكل صريح أم لا. يحاول العنصر الإنشائي Grid تلقائيًا وضع عنصر في واجهة المستخدم في خلية الشبكة المتاحة في الصف. وإذا لم يتمكّن من ذلك، يضعه في خلية شبكة متاحة في الصف التالي. إذا لم تكن هناك خلايا فارغة، ينشئ العنصر الإنشائي Grid صفًا جديدًا.

في المثال التالي، تحتوي الشبكة على ست خلايا شبكة وتضع بطاقة في كل منها (الشكل 1). تبلغ أبعاد كل خلية شبكة 160dp × 90dp، ما يجعل إجمالي حجم الشبكة 320dp × 270dp.

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
    }
) {
    Card1()
    Card2()
    Card3()
    Card4()
    Card5()
    Card6()
}

يتم وضع ست بطاقات في شبكة تتضمّن ثلاثة صفوف وعمودَين.
الشكل 1. تم وضع ست بطاقات في شبكة تتضمّن ثلاثة صفوف وعمودَين.

لتغيير هذا السلوك التلقائي إلى التعبئة حسب العمود، اضبط السمة flow على GridFlow.Column.

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
        gap(8.dp)
        flow = GridFlow.Column // Grid tries to place items to fill the column
    },
) {
    Card1()
    Card2()
    Card3()
    Card4()
    Card5()
    Card6()
}

تغيّر دالة التدفق اتجاه وضع العناصر.
الشكل 2 : GridFlow.Row (على اليمين) وGridFlow.Column (على اليسار)

إدارة حجم المسار

يُشار إلى الصفوف والأعمدة بشكل جماعي باسم مسار الشبكة. يمكنك تحديد حجم مسار الشبكة باستخدام إحدى الطرق التالية:

  • ثابت (Dp): يتم تخصيص حجم معيّن (مثلاً، column(180.dp)).
  • النسبة المئوية (Float): يتم تخصيص نسبة مئوية من إجمالي المساحة المتاحة من 0.0f إلى 1.0f (مثلاً، row(0.5f) لـ %50).
  • مرن (Fr): يتم توزيع المساحة المتبقية بالتناسب بعد احتساب المسارات الثابتة والنسبة المئوية. على سبيل المثال، إذا تم ضبط صفَّين على 1.fr و3.fr، يتلقّى الصف الأخير% 75 من الارتفاع المتبقي.
  • جوهرية: يتم تحديد حجم المسار استنادًا إلى المحتوى بداخله. لمزيد من المعلومات، يُرجى الاطّلاع على تحديد حجم مسار الشبكة بشكل جوهري.

يستخدم المثال التالي خيارات مختلفة لتحديد حجم المسار لضبط ارتفاعات الصفوف:

Grid(
    config = {
        column(1f)

        row(100.dp)
        row(0.2f)
        row(1.fr)
        row(GridTrackSize.Auto)
    },
    modifier = Modifier.height(480.dp)
) {
    PastelRedCard("Fixed(100.dp)")
        PastelGreenCard("Percentage(0.2f)")
    PastelBlueCard("Flex(1.fr)")
        PastelYellowCard("Auto")

}

ارتفاعات الصفوف المحدّدة باستخدام خيارات تحديد حجم المسار الأربعة الأساسية
الشكل 3 : ارتفاعات الصفوف المحدّدة باستخدام خيارات تحديد حجم المسار الأربعة الأساسية في Grid

ضبط الحد الأدنى لحجم مسارات الشبكة المرنة

عندما لا تحتوي حاوية الشبكة على مساحة متبقية، يمكن أن يتقلّص المسار المرن العادي إلى 0.dp. لمنع حدوث ذلك وضمان عدم ضغط المحتوى، استخدِم GridTrackSize.MinMax لفرض حد أدنى صريح للحجم مع الحفاظ على مرونة المسار.

يخصّص المثال التالي ما لا يقل عن 100.dp للصف الأول:

Grid(
    config = {
        column(1f)
        // The first row has a minimum height of 100.dp and can expand to 
        // the half of the remaining space.
        row(GridTrackSize.MinMax(100.dp, 1.fr))
        // The second row takes the half of the remaining space.
        row(1.fr)
        // The third row has a fixed height of 200.dp.
        row(200.dp)
    },
    modifier = Modifier.size(360.dp) // Total grid height is 360.dp
) {
    PastelRedCard("MinMax(100.dp, 1.fr)")
        PastelGreenCard("Flex(1.fr)")
    PastelBlueCard("Fixed(200.dp)")
}

ارتفاعات الصفوف المحدّدة باستخدام خيارات تحديد حجم المسار الأربعة الأساسية
الشكل 4. يبلغ ارتفاع الصف الأول 100.dp على الأقل.

ضبط الحد الأدنى لحجم مسار الشبكة لوضع القوائم الكسولة

تستعلم المسارات المرنة العادية تلقائيًا عن الأحجام الجوهرية للعناصر الفرعية لإنشاء حجم أساسي. ومع ذلك، يحظر Jetpack Compose الاستعلام عن الأحجام الجوهرية لـ SubcomposeLayout، التي تدعم مكوّنات، مثل LazyColumn و LazyRow.

يؤدي وضع قائمة كسولة داخل مسار مرن عادي إلى حدوث عطل IllegalStateException. لوضع القوائم الكسولة بأمان داخل مسار شبكة مرن، استخدِم MinMax مع حد أدنى صريح للحجم (مثل 0.dp) لتجاوز عملية القياس الجوهرية.

Grid(
    config = {
        column(1f)
        // The first row's height is determined by the height of the Text composable.
        row(GridTrackSize.Auto)
        // The second row occupies the remaining space, allowing the LazyColumn to scroll.
        row(GridTrackSize.MinMax(0.dp, 1.fr))

        gap(8.dp)
    },
    modifier = Modifier.size(width = 170.dp, height = 240.dp)
) {
    Text("LazyColumn in a Grid")
    // The LazyColumn is placed in the second row, filling the remaining space.
    LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) {
        items(100) { number ->
            PastelGreenCard("Card $number")
        }
    }
}

ارتفاعات الصفوف المحدّدة باستخدام خيارات تحديد حجم المسار الأربعة الأساسية
الشكل 5. LazyColumn في خلية شبكة

تحديد حجم مسار الشبكة بشكل جوهري

يمكنك استخدام تحديد الحجم الجوهري لـ Grid عندما تريد أن يتكيّف التنسيق مع المحتوى، بدلاً من فرضه في حاوية ثابتة. يتم تحديد حجم مسار الشبكة باستخدام القيم التالية:

  • GridTrackSize.MaxContent: استخدِم الحد الأقصى للحجم الجوهري للمحتوى (مثلاً، يتم تحديد العرض حسب الطول الكامل للنص في كتلة نصية بدون التفاف).
  • GridTrackSize.MinContent: استخدِم الحد الأدنى للحجم الجوهري للمحتوى (مثلاً، يتم تحديد العرض حسب أطول كلمة واحدة في كتلة نصية).
  • GridTrackSize.Auto: استخدِم حجمًا مرنًا لمسار يتكيّف استنادًا إلى المساحة المتاحة. يتصرف هذا الخيار مثل MaxContent تلقائيًا، ولكنّه يتقلّص ويغلّف محتواه ليناسب الحاوية الرئيسية.

يضع المثال التالي نصَّين جنبًا إلى جنب. يتم تحديد حجم عمود النص الأول حسب الحد الأدنى المطلوب لعرض النص، ويعتمد عرض العمود الثاني على الحد الأقصى المطلوب لعرض النص.

Grid(
    config = {
        column(GridTrackSize.MinContent)
        column(GridTrackSize.MaxContent)
        row(1.0f)
    },
    modifier = Modifier.width(480.dp)
) {
    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.")
    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.")
}

الأحجام الجوهرية المحدّدة في الأعمدة
الشكل 5. الأحجام الجوهرية المحدّدة في الأعمدة

ضبط الفواصل بين الصفوف والأعمدة

بعد تحديد حجم مسارات الشبكة، يمكنك تعديل فواصل الشبكة لتحسين التباعد بين المسارات. يمكنك تحديد فواصل الأعمدة باستخدام الدالة columnGap، وفواصل الصفوف باستخدام rowGap. في المثال التالي، هناك فاصل 16dp بين كل صف، وفاصل 8dp بين كل عمود (الشكل 5).

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
        rowGap(16.dp)
        columnGap(8.dp)
    }
) {
    Card1()
    Card2()
    Card3()
    Card4()
    Card5()
    Card6()
}

الفراغات بين الصفوف والأعمدة
الشكل 6. الفواصل بين الصفوف والأعمدة

يمكنك أيضًا استخدام الدالة الملائمة gap لتحديد فواصل لها نفس حجم العمود والصف، ولتحديد أحجام الأعمدة والفواصل بشكل منفصل باستخدام دالة واحدة. يضيف الرمز التالي فواصل 8dp إلى الشبكة:

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
        gap(8.dp) // Equivalent to columnGap(8.dp) and rowGap(8.dp)
    }
) {
    Card1()
    Card2()
    Card3()
    Card4()
    Card5()
    Card6()
}

تحديد مناطق الشبكة باستخدام المناطق المُسمّاة

تسمح لك المناطق المُسمّاة بإرفاق أسماء بمجموعات من خلايا الشبكة، تُعرف باسم مناطق الشبكة. يمكنك استخدام هذه الأسماء بدلاً من فهارس الإحداثيات عند وضع عناصر واجهة المستخدم في الشبكة.

يوفّر استخدام المناطق المُسمّاة فائدتَين رئيسيتَين لتحسين إمكانية قراءة الرمز:

  • عند تحديد تنسيق الشبكة، يكون الغرض من المحتوى المتوقّع وموضعه واضحًا.
  • عند إضافة المحتوى، يكون الغرض من هذا المحتوى واضحًا.

لتنظيم التنسيقات المعقدة بوضوح، يمكنك فصل بنية الشبكة الفعلية عن موضع العناصر الفرعية من خلال تحديد مناطق شبكة دلالية.

داخل تعبير لامدا config، استخدِم الدالة area في GridConfigurationScope لتسجيل المناطق المُسمّاة في الشبكة. يمكنك بعد ذلك تعيين العناصر الإنشائية الفرعية لهذه المناطق باستخدام المعدِّل gridItem مع معرّف المنطقة المقابل. تربط الدالة area معرّفًا دلاليًا (مثل قيمة فئة enum أو مفتاح سلسلة) بمجموعة من إحداثيات الشبكة الفعلية. تستند خطوط الشبكة والفهارس إلى الرقم 1 (أي أنّ الصف الأول هو 1 والعمود الأول هو 1).

على سبيل المثال، يمكنك تحديد شبكة تتضمّن أربعة معرّفات مناطق:

/**
 * An enum representing the IDs for named areas within the grid.
 */
enum class GridAreaNames {
    Area1,
    Area2,
    Area3,
    Area4
}

قدِّم اسم المنطقة باستخدام المَعلمة areaId مع إحداثيات الخلايا والنطاقات الخاصة بالمنطقة. يستخدم المعدِّل gridItem السمة areaId كمفتاح لتعيين كل عنصر فرعي لمنطقة الشبكة المخصّصة له، كما هو موضّح في المثال التالي:

Grid(
    config = {
        // Define a single column that takes all available width.
        repeat(2) { column(0.5f) }

        // Define four rows, each taking 25% of the total height.
        repeat(4) { row(0.25f) }

        // Define named grid areas by associating an areaId with specific row and column indices.
        // Row and column indices are 1-based.
        area(areaId = GridAreaNames.Area1, row = 1, column = 1, columnSpan = 2)
        area(areaId = GridAreaNames.Area2, row = 2, column = 1, rowSpan = 3)
        area(areaId = GridAreaNames.Area3, rows = 2..3, columns = 2..2)
        area(areaId = GridAreaNames.Area4, row = 4, column = 2)

        gap(4.dp)
    },
    modifier = Modifier.size(360.dp)
) {
    PastelRedCard(
        "Area 1",
        // Use Modifier.gridItem(areaId) to place this composable into the
        // grid area defined with the matching ID in the config block.
        modifier = Modifier.gridItem(areaId = GridAreaNames.Area1)
    )
    PastelGreenCard(
        "Area 2",
        modifier = Modifier.gridItem(areaId = GridAreaNames.Area2)
    )
    PastelBlueCard(
        "Area 3",
        modifier = Modifier.gridItem(areaId = GridAreaNames.Area3)
    )
    PastelYellowCard(
        "Area 4",
        modifier = Modifier.gridItem(areaId = GridAreaNames.Area4)
    )
}

باستخدام المناطق المُسمّاة، يمكنك إعادة تنظيم شبكة التنسيق الفعلي أو تعديلها (على سبيل المثال، تغيير الصفوف أو الأعمدة أو أحجام المسارات) في تعبير لامدا config بدون الحاجة إلى تعديل ترتيب العناصر الإنشائية الفرعية أو مَعلماتها.