İçeriğe geç
academia.sh

Ders 11 / 17

Hazır Arayüz Bileşenleri

Düğme gibi hazır arayüz bileşenlerinin içeriğine verdiği rengin ağaçta hangi yöne gittiğinin ve içeriği bir düzenle sarmanın bu yönü nasıl değiştirdiğinin ölçümü.

Yayın Güncelleme

Bu derste

  • Hazır bir düğmenin içeriğine rengi derin yönde verdiğini ölçer
  • İçeriği bir düzenle sarmanın rengin yönünü aşağıdan derine çevirdiğini gösterir
  • Rengi alan ögenin sağlayıcıya olan uzaklığını ağaç üzerinde okur
  • Hazır bir arayüz bileşeninin içerik yuvasının çocuk ağacını nasıl kurduğunu açıklar
İçindekiler

Tasarım sistemi, sık gereken parçaları hazır sunar: düğme, kart, metin alanı, anahtar, onay kutusu. Bu parçaları kullanan geliştirici rengi, kenar yuvarlaklığını ya da dokunma davranışını yeniden yazmaz. Bunun karşılığında bir şey sorması gerekir: düğmenin içine koyduğu simge ve metin, rengini nereden alıyor? Düğmenin arka planı koyu ise içindeki metin açık olmalıdır; bu karar bir yerde verilir ve içeriğe bir yoldan ulaşır.

Bu dersin ölçü eksenindeki soru, o yolun yönüdür. Düğme içeriğine renk sağlar. İçerik düğmenin hemen altındaysa renk bir kat aşağı iner. İçerik bir düzenle sarılmışsa renk araya giren düğümü atlayarak iner. Yön bu iki durumda farklı adlar taşır.

// Direction.kt — bir verinin arayuz agacinda hangi yone gittigini siniflandirir
class Tree(private val parentOf: Map<String, String>) {
    fun contains(node: String): Boolean = node in parentOf.keys || node in parentOf.values
    fun parent(node: String): String? = parentOf[node]
    fun ancestors(node: String): List<String> {
        val chain = mutableListOf<String>()
        var current = parentOf[node]
        while (current != null) {
            chain.add(current)
            current = parentOf[current]
        }
        return chain
    }
}

class Move(val label: String, val from: String, val to: String, tree: Tree) {
    val direction: String = when {
        !tree.contains(from) || !tree.contains(to) -> "dis"
        to in tree.ancestors(from) -> "yukari"
        tree.parent(to) == from -> "asagi"
        from in tree.ancestors(to) -> "derin"
        else -> error("akrabasiz: $from ve $to")
    }

    fun describe() {
        println("$label: kimden=$from | kime=$to -> $direction")
    }
}

fun countDirections(moves: List<Move>) {
    for (name in listOf("asagi", "yukari", "derin", "dis")) {
        println("$name: ${moves.count { it.direction == name }}")
    }
}

Düğme ve İçerik Yuvası

Hazır düğme, bir tıklama işlevi ve bir içerik yuvası alır. Yuva, düğmenin içinde ne duracağını çağıran belirler: yalnız bir metin, yalnız bir simge ya da ikisi birden. Düğme bu yuvayı kendi çocuk ağacına yerleştirir ve yuvadaki ögelerin okuyacağı içerik rengini sağlar.

// Platform kodu: hazir dugme ve icerik yuvasi
@Composable
fun SaveButton(onSave: () -> Unit) {
    Button(onClick = onSave) {
        Row {
            Icon(Icons.Default.Check, contentDescription = null)
            Text("Kaydet")
        }
    }
}

Buradaki Row, yuvanın içinde yazılmıştır, yani düğmenin çocuğudur; Icon ve Text ise Row’un çocuklarıdır. Düğme içerik rengini oluşturma yereli (LocalContentColor) üzerinden sağlar. Icon ve Text, rengi parametre olarak almak yerine bu yerelden okur. Yerelin ayrıntısı tema dersindedir; bu derste yalnız renk hareketinin yönü ölçülür.

Model, platformun bu kuralını kurar; model platformun kendisi değildir. Aşağıdaki yardımcı dosya düğmenin ağacını iki biçimde kurar: içerik düğmenin doğrudan altında ya da bir Row içinde. Ayrıca düğmenin arka plan rengine göre içerik rengini seçen küçük bir kural içerir ve hangi ögelerin rengi okuduğunu söyler.

// Button.kt — dugme agaci ve icerik rengi (modelin hesabi)
fun buttonTree(content: List<String>, wrapped: Boolean): Tree {
    val parentOf = mutableMapOf("Screen" to "App", "Button" to "Screen")
    val holder = if (wrapped) "Row" else "Button"
    if (wrapped) {
        parentOf["Row"] = "Button"
    }
    for (child in content) {
        parentOf[child] = holder
    }
    return Tree(parentOf)
}

fun contentColorFor(container: String): String =
    if (container == "koyu") "acik" else "koyu"

fun colorReaders(content: List<String>): List<String> =
    content.filter { it.startsWith("Icon") || it.startsWith("Text") }

Sarılı İçerik

İlk ölçümde içerik bir Row ile sarılıdır. Düğme koyu bir arka plan taşır; içerik rengi açık seçilir ve rengi okuyan her ögeye düğmeden gider.

// Main.kt — Row ile sarili icerik
fun main() {
    val content = listOf("Icon", "Text")
    val tree = buttonTree(content, wrapped = true)
    println("icerik rengi: ${contentColorFor("koyu")}")
    val moves = colorReaders(content).map { Move("renk-${it.lowercase()}", "Button", it, tree) }
    for (move in moves) {
        move.describe()
    }
    countDirections(moves)
}
icerik rengi: acik
renk-icon: kimden=Button | kime=Icon -> derin
renk-text: kimden=Button | kime=Text -> derin
asagi: 0
yukari: 0
derin: 2
dis: 0

İki hareketin ikisi de derin. Renk düğmeden çıktı; hedefin ebeveyni düğme değil Row olduğu için hareket doğrudan çocuğa varmadı, bir düğümü atlayarak indi. Araya giren Row, renkle hiçbir şey yapmaz: onu ne okur ne değiştirir. Renk onun yanından geçer.

AD1. Model düğmenin arka plan rengini iki değerden biri olarak alır ve içerik rengini bu ikiliden seçer. Platformun gerçek renk hesabı, kontrast oranı ve etkin olmayan düğmenin soluk rengi modelde yoktur.

Sarısız İçerik

İkinci ölçümde aynı iki öge düğmenin doğrudan altındadır. Düğme aynı rengi veriyor, aynı ögeler aynı rengi okuyor. Değişen tek şey aradaki Row’un yokluğudur.

// Main.kt — dogrudan altindaki icerik
fun main() {
    val content = listOf("Icon", "Text")
    val tree = buttonTree(content, wrapped = false)
    val moves = colorReaders(content).map { Move("renk-${it.lowercase()}", "Button", it, tree) }
    for (move in moves) {
        move.describe()
    }
    countDirections(moves)
}
renk-icon: kimden=Button | kime=Icon -> asagi
renk-text: kimden=Button | kime=Text -> asagi
asagi: 2
yukari: 0
derin: 0
dis: 0

Bu kez iki hareket de aşağı. Renk aynı, kaynak aynı, hedef aynı; yön, aradaki düğümün varlığına bağlı olarak değişti. Bir hareketin yönü verinin kendi özelliği olmadığından, kodu okurken “bu renk aşağı gider” demek yerine “bu renk, bu ağaçta aşağı gider” demek gerekir.

AD2. Model yalnız iki ağaç biçimini karşılaştırır. Düğmenin birden çok kat sarılması, sarmalayanın kendi yerel değerini sağlaması ya da içeriğin yuvadan dışarı çıkarılması modelde ölçülmedi.

Sınırlayıcı Ölçüm

Dersin yönünü, her iki ağaçtaki hareketleri yan yana koyunca görmek mümkün olur. Aşağıdaki ölçüm üç hareket içerir: arka plan rengi ekrandan düğmeye, sonra iki farklı sarma biçimi için içerik rengi düğmeden simgeye.

// Main.kt — iki agacin yan yana dokumu
fun main() {
    val content = listOf("Icon", "Text")
    val wrappedTree = buttonTree(content, wrapped = true)
    val plainTree = buttonTree(content, wrapped = false)
    val moves = listOf(
        Move("zemin-rengi", "Screen", "Button", plainTree),
        Move("sarili-simge", "Button", "Icon", wrappedTree),
        Move("sarili-metin", "Button", "Text", wrappedTree),
        Move("sarisiz-simge", "Button", "Icon", plainTree),
    )
    for (move in moves) {
        move.describe()
    }
    countDirections(moves)
}
zemin-rengi: kimden=Screen | kime=Button -> asagi
sarili-simge: kimden=Button | kime=Icon -> derin
sarili-metin: kimden=Button | kime=Text -> derin
sarisiz-simge: kimden=Button | kime=Icon -> asagi
asagi: 2
yukari: 0
derin: 2
dis: 0

Bu bloktaki dört satırın ikişer ucu da elle yazılmıştır: bu satırlar iki ağacı yan yana göstermek için yazılmıştır, ölçüm değildir. Dersin derin yönü, uçları colorReaders işlevinden gelen önceki ölçüme dayanır.

İki aşağı, iki derin. Ekrandan düğmeye giden zemin rengi doğrudan çocuğa gider: aşağı. Aynı ögeye giden içerik rengi, arada bir düzen varsa derin, yoksa aşağıdır. Hazır arayüz bileşenlerinin ilginç yanı budur: düğme kendi içeriğine rengi veriyor ama içeriğin hangi derinlikte durduğunu bilmiyor. Çağıran yuvaya ne yazarsa yazsın renk oraya ulaşır. Derin yön, bunu mümkün kılan hareket çeşididir.

Bu yüzden hazır arayüz bileşeninin içeriğini düzenlemek renk için güvenlidir; içeriği bir Row ya da Box ile sarmak rengi kesmez. Renk, ağaç boyunca bir ata tarafından sağlandığı sürece, derindeki ögeye ulaşır. Dersin yönü: derin.

AD3. Model rengi yalnız Icon ve Text adlı ögelerin okuduğunu varsayar. Kendi çizimini yapan bir özel ögenin rengi okuması için ne yapması gerektiği bu derste ölçülmedi.

Özet

  • Bu dersin yönü: derin. Düğme ile içerik arasına bir düzen girince renk, araya giren düğümü atlayarak ulaşır.
  • Hazır arayüz bileşeni, ortak davranışı ve görünümü hazır sunar; içeriği bir yuva üzerinden çağıran belirler.
  • Düğme içeriğine rengi verir; içerik düğmenin doğrudan altındaysa renk aşağı gider.
  • İçerik bir düzenle sarılırsa aynı renk, araya giren düğümü atlayarak derin gider.
  • Yön, verinin değil ağacın özelliğidir: aynı renk iki ağaçta iki farklı yön taşır.

Sonraki Adım

Düğme, içeriğine renk verdi; iskele ise içeriğine boşluk verir. Sonraki ders, ekranın üst çubuğu, alt çubuğu ve içeriğini bir arada tutan iskelenin içeriğe verdiği boşluğun yönünü ölçer.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ ↵ Esc gezin · aç · kapat