Kapsayıcı özelliklerini ayarlama

Farklı ekran boyutlarına ve içerik türlerine yanıt veren esnek düzenler oluşturmak için bir ızgara kapsayıcı yapılandırması tanımlayabilirsiniz. Bu sayfada aşağıdakilerin nasıl yapılacağı açıklanmaktadır:

Izgara tanımlama

Izgara, sütun ve satırlardan oluşur. Grid composable'ı, GridConfigurationScope içindeki sütunları ve satırları tanımlamak için lambda kabul eden bir config parametresine sahiptir. Aşağıdaki örnekte, her biri Dp cinsinden belirtilen sabit boyuta sahip üç satır ve iki sütundan oluşan bir tablo tanımlanmaktadır:

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

Öğeleri ızgaraya yerleştirme

Grid, content lambda'sındaki kullanıcı arayüzü öğelerini alıp kılavuz hücrelerine yerleştirir. Izgara, satırları ve sütunları açıkça tanımlayıp tanımlamadığınıza bakılmaksızın öğeleri yerleştirir. Varsayılan olarak Grid, kullanıcı arayüzü öğesini satırdaki kullanılabilir ızgara hücresine yerleştirmeye çalışır. Bunu yapamazsa öğeyi bir sonraki satırdaki kullanılabilir ızgara hücresine yerleştirir. Boş hücre yoksa Grid yeni bir satır oluşturur.

Aşağıdaki örnekte, ızgarada altı hücre vardır ve her birine bir kart yerleştirilmiştir (Şekil 1). Her bir ızgara hücresi 160dp x 90dp boyutunda. Toplam ızgara boyutu ise 320dp x 270dp.

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

Altı kart, üç satır ve iki sütundan oluşan bir ızgaraya yerleştirilir.
Şekil 1. Altı kart, üç satır ve iki sütundan oluşan bir ızgaraya yerleştirilir.

Bu varsayılan davranışı sütuna göre doldurma olarak değiştirmek için flow özelliğini GridFlow.Column olarak ayarlayın.

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()
}

Akış işlevi, öğelerin yerleştirileceği yönü değiştirir.
Şekil 2. GridFlow.Row (sol) ve GridFlow.Column (sağ).

Parça boyutlandırmayı yönetme

Satırlar ve sütunlar toplu olarak ızgara yolu olarak adlandırılır. Izgara parçasının boyutunu aşağıdaki yöntemlerden birini kullanarak belirtebilirsiniz:

  • Sabit (Dp): Belirli bir boyut (ör. column(180.dp)) ayırır.
  • Yüzde (Float): 0.0f ile 1.0f arasındaki toplam kullanılabilir alanın bir yüzdesini tahsis eder (ör. %50 için row(0.5f)).
  • Esnek (Fr): Sabit ve yüzdelik parçalar hesaplandıktan sonra kalan alanı orantılı olarak dağıtır. Örneğin, iki satır 1.fr ve 3.fr olarak ayarlanırsa ikincisi kalan yüksekliğin% 75'ini alır.
  • İçsel: Parçayı içindeki içeriğe göre boyutlandırır. Daha fazla bilgi için Izgara parça boyutunu içsel olarak belirleme bölümüne bakın.

Aşağıdaki örnekte, satır yüksekliklerini tanımlamak için farklı parça boyutlandırma seçenekleri kullanılmaktadır:

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")

}

Dört birincil kanal boyutlandırma seçeneği kullanılarak tanımlanan satır yükseklikleri.
Şekil 3. Grid içindeki dört ana kanal boyutlandırma seçeneği kullanılarak tanımlanan satır yükseklikleri.

Esnek ızgara kanalları için minimum boyutu ayarlama

Izgara kapsayıcısında boş alan kalmadığında standart esnek bir kanal 0.dp değerine kadar küçülebilir. Bunu önlemek ve içeriğin sıkışmamasını sağlamak için GridTrackSize.MinMax kullanarak parçayı esnek tutarken açık bir minimum boyut uygulayın.

Aşağıdaki örnekte, ilk satıra en az 100.dp tahsis edilmektedir:

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)")
}

Dört birincil kanal boyutlandırma seçeneği kullanılarak tanımlanan satır yükseklikleri.
Şekil 4. İlk satırın yüksekliği en az 100.dp.

Yavaş yüklenen listeleri yerleştirmek için minimum ızgara kanalı boyutunu ayarlama

Standart esnek kanallar, temel bir boyut oluşturmak için alt öğelerinin iç boyutlarını otomatik olarak sorgular. Ancak Jetpack Compose, LazyColumn ve LazyRow gibi bileşenleri destekleyen SubcomposeLayout'nin iç boyutlarının sorgulanmasına izin vermez.

Standart bir esnek parçanın içine geç yüklenen liste yerleştirmek IllegalStateException kilitlenmesine neden olur. Tembel listeleri esnek bir ızgara kanalına güvenli bir şekilde yerleştirmek için içsel ölçüm aşamasını atlamak üzere açık bir minimum boyuta (ör. 0.dp) sahip MinMax kullanın.

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")
        }
    }
}

Dört birincil kanal boyutlandırma seçeneği kullanılarak tanımlanan satır yükseklikleri.
5. şekil. Izgara hücresinde LazyColumn.

Izgara parça boyutunu içsel olarak belirleme

Düzenin sabit bir kapsayıcıya sığdırılması yerine içeriğe uyum sağlamasını istediğinizde Grid için içsel boyutlandırmayı kullanabilirsiniz. Izgara yolu boyutu aşağıdaki değerlerle belirlenir:

  • GridTrackSize.MaxContent: İçeriğin maksimum iç boyutunu kullanır (ör. genişlik, kaydırma yapılmayan bir metin bloğundaki metnin tam uzunluğuna göre belirlenir).
  • GridTrackSize.MinContent: İçeriğin minimum iç boyutunu kullanır (ör. genişlik, bir metin bloğundaki en uzun tek kelimeye göre belirlenir).
  • GridTrackSize.Auto: Kullanılabilir alana göre uyarlanan bir kanal için esnek bir boyut kullanın. Varsayılan olarak MaxContent gibi davranır ancak içeriğini üst kapsayıcıya sığacak şekilde küçültür ve sarmalar.

Aşağıdaki örnekte iki metin yan yana yerleştirilmiştir. İlk metnin sütun boyutu, metni görüntülemek için gereken minimum genişliğe göre belirlenir. İkinci sütunun genişliği ise metnin gereken maksimum genişliğine bağlıdır.

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.")
}

Sütunlarda belirtilen içsel boyutlar.
5. şekil. Sütunlarda belirtilen içsel boyutlar.

Satırlar ve sütunlar arasındaki boşlukları ayarlama

Izgara kanallarınız boyutlandırıldıktan sonra, kanallar arasındaki boşluğu hassas bir şekilde ayarlamak için ızgara boşluğunu değiştirebilirsiniz. Sütun boşluğunu columnGap işleviyle, satır boşluğunu ise rowGap ile belirtebilirsiniz. Aşağıdaki örnekte, her satır arasında 16dp, her sütun arasında ise 8dp boşluk vardır (Şekil 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()
}

Satırlar ve sütunlar arasındaki boşluklar.
6. şekil. Satırlar ve sütunlar arasındaki boşluklar.

Aynı sütun ve satır boyutundaki boşlukları tanımlamak ve tek bir işlev kullanarak sütun ve boşluk boyutlarını ayrı ayrı tanımlamak için gap kolaylık işlevini de kullanabilirsiniz. Aşağıdaki kod, ızgaraya 8dp boşluk ekler:

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()
}

Adlandırılmış alanlarla ızgara alanlarını tanımlama

Adlandırılmış alanlar, ızgara alanları olarak adlandırılan ızgara hücresi gruplarına ad eklemenize olanak tanır. Kullanıcı arayüzü öğelerini ızgaraya yerleştirirken koordinat dizinleri yerine bu adları kullanabilirsiniz.

Adlandırılmış alanları kullanmanın kod okunabilirliği açısından iki temel avantajı vardır:

  • Izgara düzeni tanımlanırken beklenen içeriğin amacı ve yerleşimi net olmalıdır.
  • İçerik eklenirken içeriğin amacı net bir şekilde belirtilmelidir.

Karmaşık düzenleri net bir şekilde organize etmek için anlamsal ızgara alanları tanımlayarak fiziksel ızgara yapınızı alt öğe yerleşiminden ayırabilirsiniz.

config lambda'sının içinde, GridConfigurationScope'teki area işlevini kullanarak ızgaradaki adlandırılmış alanları kaydedin. Ardından, ilgili alan tanımlayıcısıyla gridItem değiştiricisini kullanarak bu alanlara alt composable'lar atayabilirsiniz. area işlevi, anlamsal bir tanımlayıcıyı (ör. enum sınıf değeri veya dize anahtarı) bir dizi fiziksel ızgara koordinatıyla eşler. Izgara çizgileri ve dizinler 1 tabanlıdır (yani ilk satır 1, ilk sütun ise 1 olur).

Örneğin, dört alan kimliği içeren bir ızgara tanımlarsınız:

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

areaId parametresini kullanarak alanın adını, hücre koordinatlarını ve aralıklarını belirtin. gridItem değiştiricisi, her alt öğeyi belirlenen ızgara alanına atamak için areaId anahtarını kullanır. Bu durum aşağıdaki örnekte gösterilmiştir:

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)
    )
}

Adlandırılmış alanları kullanarak, alt composable'ların sırasını veya parametrelerini değiştirmenize gerek kalmadan config lambda'da fiziksel düzen ızgarasını yeniden düzenleyebilir ya da ayarlayabilirsiniz (ör. satırları, sütunları veya kanal boyutlarını değiştirme).