Jetpack Compose ve Clean Architecture Yaklaşımı ile Kütüphane Sistemi — 3 (Parametre Ekranları)

mesut emre çelenk
3 min readJun 4, 2022

Merhabalar,

Bir önceki yazımda uygulamada kullanacağım compose componentlerin (TopBar,BottomNavigation vs.) genel yapısı ve uygulama içi navigation hakkında bişeyler karalamıştım. O yazıya buradan ulaşabilirsiniz.

Bu yazımda ise sizlere uygulamanın bottomnavigation componentinde bir menu item olan parametre ekranlarından ve bu ekranların ilki olan Yayınevi ekranından bahsedeceğim. Burada parametre tabına ait ekran görüntüsü aşağıdaki gibidir.

Bu ekrandaki her bir menu item KutuphanemMenuItem componentidir.

Navigation tarafında ise ekranlarımızı aşağıdaki gibi tanımlamalıyız. Zaten yukarıdaki kodda dikkat ettiyseniz bir trailer lambda mevcut. Bu da menu item a basınca alacağımız actionun ta kendisidir.

Şimdi gelelim ParametreYayinEviScreen ekranına. Burada şöyle bir akışımız mevcut.

Ekran ilk kez açılıyorsa servis çağrısı yapılır. Bu çağrı esnasında ekranda loader gösterilir. Servis çağrısı başarılı bir şekilde sonuçlanırsa yani liste dönerse LazyColumn’a bu liste basılır. Liste artık elimizde ve parametrelerde genelde değişmeyeceği için Room ile bu dataları local db de tutacağız. Ve sonraki çağrılarımızda SharedPreferences’a setlediğimiz bir key ile ilk önce dataları DB’ye yazıp yazmadığımızı kontrol edip, datalar localimizde var ise DB’den , yoksa API’den alacağız. Ya da istediğimiz zaman SwipeRefresh ile API call yapabileceğiz.

Yok eğer liste alınamadı ise kullanıcıya bunun bilgisini dönen bir componenti göstereceğiz.

Bu ekranda ayrıca listeden istenilen elemanı silme işlemide yapılabilmektedir.

Yukarıda anlattığım senaryoda 3 tane usecase mevcuttur. Bu usecaseler; Listeyi çekme,listeyi DB’ye yazma ve eleman silme. Dilerseniz ilk olarak ekranın UI kısmının kodlarına göz atalım. Daha sonra state ve viewModel ile birlikte service,dao ve repository katmanlarına göz atacağız.

Tekrar belirtmekte fayda olacak. UI,state ve viewmodel presentation packageında bulunmakta olup, service, dao, entity ve dto classları data packageında , repolar ve usecase ler ise domain packageındadır.

Burada kullandığım custom componentlere buradan ulaşabilirsiniz. Yukarıda kodlarını gördüğünüz ekran yayınevi listesini gösterdiğim ekran olup bu ekranda filtreleme yapılabilmektedir. Bu işlemler viewmodel tarafında yönetilmekte ve state üzerine setlenerek ekran recompose olmaktadır.

Ekran viewmodel tarafında usecaseler çağrılarak init oluyor.

initYayinEviList functionundaki boolean parametresini swipe refresh kontrolü için koydum. Çünkü swipe yapılınca API call yapılacak , aksi takdirde local cache de data mevcut ise oradan alınacak. Data nın usecase kullanılarak çekilme işlemi ise aşağıda mevcuttur.

Datanın local DB de olup olmadığı bilgisini yukarıda senaryoyu yazarken söylemiştim. Bu bilgiyi pref’den aşağıdaki gibi alıyoruz.

Burada dikkat ettiyseniz usecase ‘ e inject edilen StoreYayinEviParametre adında bir usecase var. Bu usecase local db ye kayıt atılan usecasedir. Aslında bunuda viewmodel e inject edip isDbKayit kontrolü ile viewmodel de çağırabilirdik. Fakat bu işlem viewmodel ‘ da boilerprate koda sebebiyet verip, uzunca bir business akışı barındıracaktı. Örneğin listeyi başka bir ekranda kullanmak istediğimiz zaman aynı kodu tekrar yazmak zorunda kalacaktık. Çünkü ileride kitap kaydı yapacağımız ekranda bu listeyi tekrar almamız gerekecek. Dolayısıyla bu şekilde yazarak usecase i reusable hale getirmiş oluyoruz.

Repo interfacei, Dao, API ve modeller ise ilgili packagelerında aşağıdaki gibidir.

Bu interface ler repoya inject edilerek data üzerindeki işlemler yapılır.

Burada dikkatinizi çekmek istediğim bir diğer nokta ise ekrandaki liste için ayrı, api call dan gelen liste için ayrı ve Room dan gelen liste için ise ayrı bir data class da işimi yürütmüş olmam. Bunun sebebi ; ekranda kullanmama gerek olmayan datayı UI modeline almamak ve Room entitysi ile api call un data classlarını çorba etmemek. Neticede yarın birgün api data classına eklenen bir field DB’de tutulmayabilir hatta ve hatta UI da bile lazım olmayabilir. UI da kullandığım data classı ise bu 2 classdan generate ediyorum.

toYayinEviItem() function u ile UI da bana lazım olan fieldları barındıran data classı generate etmiş oluyorum.

Bir sonraki yazımda görüşmek üzere. Sürçülisan ettiysem affola. Soru ve görüşleriniz için mesutemrecelenk@gmail.com ‘ a mail atabilirsiniz. Sağlıcakla kalın…

--

--