JetPack Compose: Getting Started

Tamer Sarioglu
Mobillium
Published in
8 min readJan 14, 2022

Merhaba,

Bu yazımızda, Android geliştirmeye yeni bir yaklaşım getiren JetPack Compose’un Tutorial’ındaki ilk 4 dersi Türkçe’ye çevirdik.

Keyifli okumalar…

Jetpack Compose, modern Android kullanıcı arayüzü(UI) oluşturmak için geliştirilen araçlar bütünüdür. Jetpack Compose, güçlü alt yapısı ile birlikte daha az kod ve sezgisel Kotlin API’leri sayesinde Android’de UI geliştirmeyi basitleştirir ve hızlandırır.

Bu eğitim boyunca, basit bir UI tasarımını bildirimsel (declarative) fonksiyonlar ile oluşturacağız. Herhangi bir XML dosyasını düzenlemeyecek veya Layout Editor kullanmayacağız. Onun yerine Jetpack Compose fonksiyonlarına hangi UI elemanını istediğimizi belirteceğiz ve gerisini Compose derleyicisi halledecek :)

Ders 1: Composable Fonksiyonlar

Jetpack Compose, composable fonksiyonlar çerçevesinde oluşturulur. Bu fonksiyonlar, uygulamanızın kullanıcı arabirimini oluşturma sürecine (bir öğeyi çağırma, bir üst öğeyi çağırma vb.) odaklanmak yerine nasıl görünmesi gerektiğini açıklayarak ve veri bağımlılıkları sağlayarak programlı olarak tanımlamanıza olanak tanır. Composable bir fonksiyon oluşturmak için fonksiyon adının üstüne @Composable ek açıklamasını eklemeniz yeterlidir.

Text Elementi Ekleyelim

Başlamak için öncelikle Android Studio Arctic Fox’un son versiyonunu indirmeniz gerekiyor. İndirdikten sonra ilk ekrandan empty compose activity template sekmesinden boş bir compose uygulaması açabiliriz. Default template zaten bazı Compose elemanları içeriyor ancak biz yine de bunları silip en baştan yazalım.

İlk olarak her zamanki gibi ekrana “Hello World” yazarak başlayalım. Bunu onCreate() metodunun içine Text() fonksiyonu çağırarak yapabiliriz. Başlangıç olarak bir içerik bloğu tanımlayarak ve Text() fonksiyonunu çağırarak bu işlemi yapabilirsiniz. Gördüğünüz setContent bloğu ise activity içindeki composable fonksiyonlarını çağırdığınız layout’u (görünüm alanı) temsil ediyor. Burada önemli bir nokta var, composable fonksiyonlar ancak başka bir composable fonksiyonlar tarafından çağrılabilir.

Jetpack Compose, Kotlin derleyici kullanarak bu composable fonksiyonları UI elementlere çevirir. Örneğin Text() fonksiyonu Compose UI kütüphanesi tarafından tanımlanarak ekrana text’in kendisi yazdırılır.

Composable Fonksiyon Tanımlama

Composable fonksiyon oluşturmak için @Composable notu fonksiyonun üstüne eklenir. Mesela, MessageCard() fonksiyonunu yazalım ve argüman olarak da string tipinde name yazalım. Bu fonksiyonu birazdan text elemanını göstermek için kullanacağız.

Android Studio’da Fonksiyon Önİzleme

Android Studio, uygulamayı android cihazınıza ya da emulatöre yüklemek yerine IDE içinde composable fonksiyonları ön-izlemenize izin verir. Composable fonksiyonlar aldığı her parametre için varsayılan bir değer almalıdır. Bu gereklilikten ötürü doğrudan MessageCard() fonksiyonuna preview ekleyemiyoruz. Onun yerine, ikinci bir fonksiyon tanımlayalım ve adı da PreviewMessageCard() olsun. Uygun parametre olarak da MessageCard() metodunu ekleyelim. @Composable’ın üstüne de @Preview’u ekleyelim.

Projeyi tekrar oluşturalım. PreviewMessageCard() metodu hiçbir yerde eklenmediği için App değişmedi; ancak Android Studio önizleme penceresi oluşturdu. Bu pencere @Preview etiketi ile etiketlenen Composable Fonksiyonların oluşturduğu UI elementlerin ön izlemesini gösterir. Önizlemeleri istediğiniz zaman güncellemek için önizleme penceresinin üst kısmındaki yenile düğmesini tıklayın.

Ders 2: LAYOUT

UI elemanları, diğer elemanlarda bulunan öğelerle birlikte hiyerarşik düzene sahiptir. Compose’da bu öğeleri, Composable fonksiyonlar ile çağırarak bir UI hiyerarşisi oluşturabilirsiniz.

Çoklu Text Ekleme

Şu ana kadar ilk composable fonksiyonumuzu ve önizlememizi oluşturduk! Jetpack Compose’un başka neler yapabildiğini görmek için animasyonlu basit bir mesajlaşma ekranı yapacağız.

Composable’ı, mesajı yazan kişiyi ve mesajımızı gösterecek şekilde zenginleştirelim. Öncelikle composable parametremizi String objesi yerine Message() objesi olarak değiştiriyoruz ve MessageCard Composable’ın içine başka bir Text() composable’ı ekliyoruz.

Bu kod, contentView içerisinde 2 adet text elementi oluşturacak. Ancak, bu text elementleri view içerisindeki yerleşimlerini henüz ayarlamadığımız için iki text elementini üst üste ve komplike bir yapıda göreceğiz.

Column Kullanmak

Column fonksiyonu, elementleri dikey olarak yerleştirmenizi sağlar. Şimdi, MessageCard() fonksiyonunun içine Column ekleyelim. Bunun yanında elementleri yatay hizalamak için Row, dikey hizalamak için de Box kullanabiliriz.

Image Ekleme

Göndericinin görselini ekleyerek message kartını daha zengin hale getirelim. Kaynak Yöneticisini (Resource Manager) kullanarak kendi kütüphanenizdeki herhangi bir imajı ya da linkteki ( this one) fotoğrafı yükleyin. İyi bir mimari için Row composable çağırıp onun da içine Image() composable’ını çağıralım.

Layout Ayarlaması

Mesaj layout’muz doğru şekilde oluşturuldu ancak layout elementleri tam da istenilen şekilde yerleştirilemedi ve fotoğraf da oldukça büyük gözüküyor. Compose bu gibi ince ayar gerektiren durumlarda Modifier’ları kullanıyor. Modifier’lar UI elementinin boyutunu, yerleşimini, görünüşünü ayarlar ya da elementi tıklanabilir hale getirmek gibi elementte üst seviye değişiklikler yapmanızı sağlar. Tüm bunları birleştirerek daha da zengin composable’lar da yaratabilirsiniz. Bunlardan birkaçını kullanarak layout’umuzu geliştirelim.

Ders 3: Materyal Dizayn

Compose, en başta material dizayn ilkelerini desteklemek için oluşturulmuştur. Çoğu UI elementi material dizayn kurallarını uygularlar. Bu derste uygulamalara material widget’lar(görsel öğeler) ekleyerek başka bir tasarım bakış açısı kazandırmaya devam edeceğiz.

Material Dizayn Kullanımı

Mesaj dizaynımız şu anda bir layout’a sahip ancak yine de olması gerektiği gibi görünmüyor. Jetpack Compose, Material Design ve UI kurallarını uygulamaya olanak sağlar. MessageCard() Composable’ımızın görünümünü geliştirmek için Material Dizayn stillerini kullanabiliriz.

Başlangıç olarak MessageCard() fonksiyonumuzu Material Theme ile saralım. Bizim projemizde bu fonksiyonun adı ComposeTutorialTheme() olacak. Bu işlemi hem @Preview hem de setContent fonksiyonları için yapalım.

Temel olarak Material Dizayn 3 temelin üstüne inşa edilmiştir. Renk, Tipografi ve Şekil. Bunları teker teker ekleyelim.

Renk (Color)

Tema ile sarılmış UI elementlerinde renk stilleri değişimi gayet kolay ve tema içindeki değerleri kullanarak istenen renklere ulaşabilirsiniz. Şimdi başlığımıza stil ekleyip fotoğrafa çerçeve ekleyelim.

Tipografi (Typography)

Material Tipografi stilleri MaterialTheme’de mevcuttur. Bu stilleri MaterialTheme kullanarak kolay bir şekilde text composable’larımıza ekleyebiliriz.

Şekil (Shape)

Shape ile son dokunuşları yapabiliriz artık. Ve aynı zamanda daha iyi bir görünüm için mesajlarımıza boşluk koyabiliriz.

Dark Mod

Dark mod özellikle az ışıklı ortamlardaki fazla parlaklığı önlemek için kullanılabilir. Dark mod aynı zamanda pil ömrünü de uzatır. Neyse ki Material Dizayn destekli Jetpack Compose dark modu en baştan bizim yerimize zaten projemize uyarlamış oluyor. Material renk, yazı stili ve arka planlar kullanıldığında her bir element kendini dark arkaplana otomatik olarak adapte ediyor. Dosyanızda, farklı fonksiyonlarla ya da aynı fonksiyona çoklu annotation ekleyerek birden çok önizleme oluşturabilirsiniz.

Şimdi gece modunu aktifleştirip yeni bir önizleme annotation’ı ekleyelim.

Light ve dark mod için renk seçenekleri IDE’nin kendi oluşturduğu Theme.kt dosyasında tanımlanmıştır.

Şu ana kadar, her biri birbirinden farklı stillerde bir image ve 2 text UI elementine sahip message UI’ı oluşturduk ve hem light hem de dark modda oldukça güzel görünüyor.

DERS 4: Listeler ve Animasyonlar

Listeler ve animasyonlar uygulamaların her yerinde bulunur ve çoğu zaman karmaşık olabilirler. Aslında Compose liste oluşturmayı oldukça kolaylaştırıyor ve animasyon eklemek çok keyifli bir hal alıyor.

Mesajlar Listesi Oluşturma

Chat kısmı, tek mesaj olduğu zaman biraz tuhaf bir izlenim bırakıyor. Dialoga çoklu mesaj ekleyerek içeriği daha zengin bir hale getirebiliriz. Bunun için çoklu mesajları gösterecek Conversation isminde yeni bir fonksiyon yazalım. Bunun için Compose’un LazyColumn ve LazyRow’unu kullanabiliriz. Bu UI elementleri sadece ekrandaki görünen nesneleri render eder ve böylece çok uzun listelerde bile etkin şekilde kullanılabilirler. Aynı zamanda da RecyclerView’ın karmaşık XML yapısından da kaçınmış oluruz.

Bu kod örneğinde, LazyColumn’un bir alt öğesini (Child) görebilirsiniz. Parametre olarak da bir Listeyi alır ve lambdası, mesaj olarak adlandırdığımız bir parametreyi alır (bunu istediğimiz şekilde adlandırabilirdik), bu da Mesaj metodunun bir örneğidir aslında. Kısaca bu lambda, sağlanan Listedeki her öğe için çağrılır: Görüşmeyi hızlı bir şekilde başlatmaya yardımcı olmak için bu örnek veri kümesini projenize aktarın.

Mesaj listesi oluşturalım.

Tek mesaja sahip bir chat ekranı oldukça yalnız görünüyor değil mi, öyleyse chatimizi birden fazla mesaj olacak şekilde değiştirelim. Bunun için bir Conversation isminde bir fonksiyon oluşturmaya ihtiyacımız var. Amacımıza daha kolay ulaşmak için de Compose’un LazyColumn ve LazyRow’unu kullanabiliriz. Bu composable’lar sadece ekranda Görünen elementleri Çizdiği için uzun listeler için de oldukça verimli çalışırlar. Aynı zamanda RecyclerView’ın karmaşık XML yapısını da göz ardı etmemize yardımcı olurlar.

Bu kod örneğindeki gibi LazyColumn bir alt öğeye sahip ve parametre olarak bir List alır, lambda ise Message’ın bir örneği olan message (ileti) adını verdiğimiz (başka bir şey de denebilir) bir parametre alır. Kısaca bu lambda fonksiyon belirtilen listedeki her eleman için çağrılabilir: örnek data için sample dataset adresindeki kodu projenize ekleyebilirsiniz. Bundan sonraki kodlarımızda bu datasetten verileri çekeceğiz.

Genişleyen Mesajlara Animasyon Ekleme

Dialog biraz daha ilgi çekici bir görünüm kazandı. Şimdi biraz da animasyonlarla oynama zamanı. Hem içerik boyutunu hem de arka plan rengini canlandırarak bir mesajı daha uzun gösterecek şekilde genişletme özelliğini ekleyeceğiz. Yerel UI durumunu saklamak için bir mesajın genişletilip genişletilmediğini takip etmemiz gerekir. Bu durum değişikliğini takip etmek için de remember ve mutableStateOf işlevlerini kullanmalıyız.

Composable fonksiyonlar, hatırlama(remember) özelliğini kullanarak yerel durumu(local state) bellekte depolayabilir ve mutableStateOf öğesine iletilen değerdeki değişiklikleri izleyebilir. Composable’lar (ve onun alt elemanları (child)), durum (state) izlenebilmesi sayesinde composable’ın temsil ettiği UI elementi, ekranda tekrar çizilerek güncellenir. Buna recomposition adı verilir.

Not: Compose’un remember ve mutableStateOf gibi durum API’lerini kullanarak, durum değişiklikleri, kullanıcı arayüzünü otomatik olarak güncellemek için ve “by”yi doğru kullanmak için aşağıdaki içe aktarmaları eklemeniz gerekecek. Alt+Enter kombinasyonu onları otomatikman ekleyecektir.

import androidx.compose.runtime.getValue

import androidx.compose.runtime.setValue

Artık isExpanded’a göre bir mesaj içeriğinin arka planını değiştirebiliriz. Composable’ımızın tıklanabilir(clickable) modifier’ını kullanarak tıklanma işini halledeceğiz. Yüzeyin yalnızca arka plan rengini değiştirmek yerine, arka plan rengini, değerini MaterialTheme.colors.surface olarak, MaterialTheme.colors.primary olarak ve bunun tersini yaparak canlandıracağız. Bunu yapmak için animateColorAsState işlevini kullanacağız. Son olarak, mesaj kapsayıcı boyutunu sorunsuz bir şekilde hareketlendirmek için animateContentSize değiştiricisini kullanıyoruz.

Kod Gösteriminde yarım kalmış kod satırı : if (isExpanded) MaterialTheme.colors.primary else MaterialTheme.colors.surface

Böylece Jetpack Compose’un ilk 4 dersini sizlere Türkçe olarak paylaşmış olduk.

Mutlu Günler…

--

--