İçeriğe geç
Educora
İleri22 dk10 / 14

Jetpack Compose ile arayüz

Ekranı composable fonksiyonlardan kur: boyut ve boşlukları Modifier ile yönet, öğeleri Row, Column, Box ve LazyColumn ile yerleştir, Material 3 bileşenlerini kullan ve sonucu @Preview ile anında gör.

Kendini test et
Bu derste öğreneceklerin
  • Parametre alan, yeniden kullanılabilir bir composable fonksiyon yazmak
  • Bir Modifier zincirini okumak ve sıranın sonucu nasıl etkilediğini açıklamak
  • Row, Column, Box ve LazyColumn ile bir ekran düzeni kurmak
  • Material 3 bileşenlerini kullanmak ve önizlemeler oluşturmak

LEGO'dan bir ev yaparken her tuğlanın bir yeri vardır: birkaç tuğla bir duvar, duvarlar bir oda, odalar da bir ev olur. Jetpack Compose'da ekran da böyle kurulur: küçük composable fonksiyonlardan (bir metin, bir düğme, bir görsel) daha büyük parçalar, onlardan da bütün bir ekran oluşur. Bu derste Educora uygulaması için bir ders kartı ve bir ders listesi kuracaksın.

Composable fonksiyonlar ve bildirimsel yaklaşım

Eski Android yönteminde ekran bir XML dosyasında tanımlanır, Kotlin kodu da öğeleri findViewById ile bulup elle değiştirirdi. Compose'da ise yalnızca verilen veriye göre ekranın nasıl görünmesi gerektiğini yazarsın; veri değişince Compose fonksiyonu yeniden çağırır. Karşılaştır:

Emirsel: XML + findViewById
// activity_main.xml contains a TextView and a Button
class MainActivity : AppCompatActivity() {
    private var count = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val label = findViewById<TextView>(R.id.label)
        val button = findViewById<Button>(R.id.button)
        button.setOnClickListener {
            count++
            label.text = "Taps: $count"
        }
    }
}
Bildirimsel: Compose
@Composable
fun TapCounter() {
    var count by remember { mutableIntStateOf(0) }
    Column {
        Text("Taps: $count")
        Button(onClick = { count++ }) {
            Text("Tap")
        }
    }
}
Solda metni kendin güncellemelisin; sağda yalnızca count değişir, ekran da buna göre kendini günceller.
  • Bir composable fonksiyon @Composable ile işaretlenir ve adı büyük harfle başlar: LessonCard.
  • Arayüz çizen bir composable hiçbir şey döndürmez (Unit); arayüzü tanımlar.
  • Veri parametrelerle gelir; son parametre genellikle modifier: Modifier = Modifier olur ki çağıran taraf görünümü ayarlayabilsin.

Modifier: boyut, boşluk, arka plan, tıklama

Modifier, bir öğenin nasıl yerleşeceğini ve nasıl davranacağını belirleyen bir zincirdir: padding, size, fillMaxWidth, background, clip, clickable vb. Zincir yukarıdan aşağıya, dıştan içe doğru uygulanır; bu yüzden sıra önemlidir:

Kotlin
Text(
    text = "Kotlin",
    modifier = Modifier
        .padding(8.dp)
        .background(Color.Yellow)
        .padding(16.dp)
        .clickable { /* open the lesson */ }
)
Sonuç: 8 dp saydam bir kenar, ardından sarı arka plan ve onun içinde metnin çevresinde 16 dp boşluk. Dokunma alanı yalnızca metin ve iç boşluktur.

Yerleşimler: Row, Column, Box, LazyColumn

YerleşimNe yapar
Columnöğeleri dikey olarak alt alta dizer
Rowöğeleri yatay olarak yan yana dizer
Boxöğeleri üst üste koyar (örneğin bir görsel ve üzerinde yazı)
LazyColumn / LazyRowuzun liste: yalnızca ekranda görünen öğeleri oluşturur
Spaceröğeler arasında boş alan

Şimdi bunları birleştirelim. LessonCard solda yuvarlak bir rozet, sağda ise başlık ve süre gösterir. Rozet bir Box'tır, metinler bir Column'dadır, ikisi de bir Row'un içindedir. Modifier.weight(1f), satırda kalan tüm boş alanı sütuna verir.

Kotlin
@Composable
fun LessonCard(title: String, minutes: Int, modifier: Modifier = Modifier) {
    Card(modifier = modifier.fillMaxWidth()) {
        Row(
            modifier = Modifier.padding(16.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Box(
                modifier = Modifier
                    .size(48.dp)
                    .clip(CircleShape)
                    .background(MaterialTheme.colorScheme.primaryContainer),
                contentAlignment = Alignment.Center
            ) {
                Text(title.first().toString())
            }
            Spacer(Modifier.width(16.dp))
            Column(modifier = Modifier.weight(1f)) {
                Text(title, style = MaterialTheme.typography.titleMedium)
                Text("$minutes min", style = MaterialTheme.typography.bodySmall)
            }
        }
    }
}
Ekranda: bir kart; solda içinde başlığın ilk harfi olan bir daire, sağda büyük yazıyla başlık ve altında küçük “15 min” yazısı.
Kotlin
@Composable
fun LessonList(lessons: List<String>, modifier: Modifier = Modifier) {
    LazyColumn(
        modifier = modifier,
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        items(lessons) { title ->
            LessonCard(title = title, minutes = 15)
        }
    }
}
Ekranda: aralarında 8 dp boşluk olan, kaydırılabilir bir kart listesi.

Material 3 bileşenleri ve tema

Material 3, Google'ın tasarım sistemidir ve Compose'da hazır bileşenler olarak gelir: Button, OutlinedButton, TextButton, Card, OutlinedTextField, Switch, Checkbox, Scaffold ve daha fazlası. Renkleri ve yazı tiplerini elle yazmak yerine MaterialTheme.colorScheme ve MaterialTheme.typography'den al; böylece koyu tema ve Android 12'den itibaren duvar kâğıdına uyan dinamik renkler kendiliğinden çalışır.

Kotlin
@Composable
fun ProfileForm(modifier: Modifier = Modifier) {
    var name by remember { mutableStateOf("") }
    var reminders by remember { mutableStateOf(true) }

    Column(
        modifier = modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        OutlinedTextField(
            value = name,
            onValueChange = { name = it },
            label = { Text("Name") }
        )
        Row(verticalAlignment = Alignment.CenterVertically) {
            Text("Daily reminders", modifier = Modifier.weight(1f))
            Switch(checked = reminders, onCheckedChange = { reminders = it })
        }
        Button(onClick = { /* save */ }, enabled = name.isNotBlank()) {
            Text("Save")
        }
    }
}
Ekranda: “Name” etiketli bir metin alanı, sağında anahtar olan “Daily reminders” satırı ve ad boş kaldıkça pasif duran “Save” düğmesi.

Dikkat et: Material bileşenleri kendi durumlarını tutmaz. OutlinedTextField metni value parametresinden alır ve yeni metni onValueChange ile sana geri verir; onu saklamak senin işin. Bunun nasıl çalıştığını bir sonraki derste ayrıntılı öğreneceksin.

Önizlemeler: uygulamayı çalıştırmadan bak

Kotlin
@Preview(showBackground = true)
@Preview(
    name = "Dark",
    showBackground = true,
    uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Composable
fun LessonCardPreview() {
    EducoraNotesTheme {
        LessonCard(title = "Jetpack Compose", minutes = 15)
    }
}
İki önizleme: aynı kart açık ve koyu temada.
  1. 1
    Split görünümünü aç

    Düzenleyicinin sağ üst köşesindeki Split düğmesine bas: solda kod, sağda önizleme görünür.

  2. 2
    Yenile

    Büyük bir değişiklikten sonra önizleme panelindeki Build & Refresh'e bas; küçük metin değişiklikleri genellikle hemen görünür.

  3. 3
    Etkileşimli mod

    Önizlemenin üstündeki etkileşimli mod düğmesine bas: artık emülatör olmadan düğmelere basabilir ve metin yazabilirsin.

hızlı düzeltme: eksik import'u eklemek (Mac: Option+Return)Alt+Enter
kodu biçimlendirmek (Mac: Cmd+Option+L)Ctrl+Alt+L
bir fonksiyonun parametrelerini göstermek (Mac: Cmd+P)Ctrl+P
tanımına gitmek, örneğin Card'ın kaynak koduna (Mac: Cmd+B)Ctrl+B
seçili kodu sarmak — Surround With (Mac: Cmd+Option+T)Ctrl+Alt+T

Önemli noktalar

  • Compose'da ekran @Composable fonksiyonlardan oluşur; ekranın nasıl görünmesi gerektiğini tarif edersin.
  • Modifier zinciri dıştan içe uygulanır; bu yüzden padding ve background'un sırası sonucu değiştirir.
  • Column dikey, Row yatay dizer, Box üst üste koyar; uzun listeler için LazyColumn kullanılır.
  • Koyu tema ve dinamik renkler kendiliğinden çalışsın diye renkleri ve yazı tiplerini MaterialTheme'den al.
  • @Preview, ekranı emülatör olmadan gösterir; bir fonksiyona birden fazla önizleme eklenebilir.

Kendini test et

10 soru. Her doğru cevap XP kazandırır.

1 / 10
500 dersin kaydırılabilir bir listesini göstermek için en iyi seçim hangisidir?