Android-DataBinding

Recep Yeşilkaya
6 min readMar 2, 2021

--

Herkese selamlar. Bugün oldukça geniş bir konu olan Data Binding‘i elimden geldiğince ifade etmeye çalışacağım. Biraz uzun bir yazı olacak. Kahveler hazırsa hadi başlayalım.

Kotlin 1.40.20-M2 güncellemesi ile Kotlin Android Extensions içerisinde kullanılan Synthetic devre dışı bırakıldığını duymuşuzdur. Peki bu ne anlam ifade ediyor? Artık oluşturduğumuz companentlere direkt ulaşamayacağız. Çözüm olarak ViewBinding, DataBinding veya findViewById kullanmamız gerekecek.

DataBinding Nedir?

Data Binding bir Android Jetpack öğesidir. XML içerisinde değişken tanımlayıp bu değişkenleri component’ler üzerinde farklı amaçlarla kullanmamıza olanak tanır. XML ile Model’in iletişimine imkan verir de diyebiliriz.

DataBinding Neye Çözüm Sunuyor?

Bir konunun iyi bir şekilde anlaşılması için neye çözüm sunduğunu anlamak oldukça önemlidir. Component‘ler üzerinde değer ataması, visibility, onClick, onTextChange gibi ifadelendirmeleri XML üzerinden yönlendirebilmemize olanak tanıyor. Böylelikle ekstra kod kalabalığından kurtuluyoruz. Ayrıca componentler için BindingAdapter da oluşturabilir, bu adapter‘larla dilediğimiz birçok işlemi gerçekleştirebiliriz. Data Binding ile Observable kullanılarak değerler değiştiğinde otomatik olarak component’ler üzerinde değişiklik yapabiliriz. Bu ve bunun gibi birçok alanda çeşitli çözümler sunmaktadır.

Yukarıda bahsettiğim gibi aslında çok uzun bir konu. Data Binding için seri şeklinde yazılmış bloglar mevcut. Elimden geldiğince ifade etmeye çalışacağım. Öyleyse haydi inişe geçelim.

İlk olarak basit bir şekilde nasıl Data Binding kullanılır onunla başlayalım.

Build.Gradle(APP)

plugins {..
id 'kotlin-kapt'}
buildFeatures {
dataBinding true}

Basit bir market modeli oluşturup , xml üzerinden bu verileri görüntüleyeceğiz.

Market Data Model

Activity Tasarım

Alt+Enter kısayolu ile XML tasarımınızı data binding formatına dönüştürebilirsiniz. Data Binding kullanmak için tüm XML’in <layout> tag’leri içerisinde yer alması gerekmektedir.

<data> içerisinde çeşitli <variable/>’lar tanımlayıp dilediğiniz type’ta değişken tanımlamaları yapabilirsiniz. Biz market model type’ında bir değişken tanımlaması yaptık. Bu değişkenin değerlerini TextView’lerde görüntülemek için ise, Text kısımlarına “@{degiskenAdi}” tanımlamalarında bulunduk.

Bu noktada binding expressions ile ne tür tanımlamalar yapabileceğinize dair bir kaynak paylaşıyorum, buradan göz atabilirsiniz.

Activity

Oluşturduğumuz Data Binding veri kaynağının belirtilmesi ve hangi sayfanın tasarımı olduğunu tanımlamak için Activity içerisinde ActivityMainBinding’den instance oluşturuyor ve gerekli tanımlamaları ifade ediyoruz (Tabii ki bu sizlerin class adlarına göre değişiklik göstermektedir). Ardından XML içerisinde tanımladığımız market modelinin değer atamasını gerçekleştiriyoruz. Peki şimdi sonucu görüntüleyelim.

Şu anlık TextView‘ler üzerinde Data Binding ile nasıl text ataması yapılır, onu ifade ettik.

“Peki bu işlem bizleri nelerden kurtardı? Normalde de bu işlemleri gerçekleştiriyorduk.” dediğinizi duyar gibiyim.

Yazımın başlarında da belirttiğim gibi Kotlin tarafından Synthetic devre dışı bırakıldı. Bu yüzden findViewById kullanmamız gerekebilirdi. Ayrıca tüm TextView’lerin text atamalarını da tek tek tanımlamanız gerekirdi. Sizce de basit bir işlem için bile oldukça uzun kod satırları değil mi? Bir de yapacağınız işler daha kompleksleşince bir düşünün. Tercih sizin. Öyleyse haydi biraz daha devam edelim.

Udacity

BindingAdapter

BindingAdapter’ları XML içerisindeki fonksiyon tanımlamaları gibi düşünebilirsiniz. Var olan parametrelerin dışında kendimize özgü işlevlerin yapılmasını istersek o zaman bindingAdapter’a ihtiyacımız olabilir. Şu anki uygulamamız için Glide kullanarak bir resim görüntüleyelim. Manifest içerisine internet izni vermeyi unutmayınız.

<uses-permission android:name="android.permission.INTERNET" />def swipeRefreshLayout = '1.1.0' 
def glideVersion = '4.9.0'
implementation "com.github.bumptech.glide:glide:$glideVersion"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:$swipeRefreshLayout"

“@BindingAdapter()” içerisinde dilediğiniz isimlendirmeyi kullanabilirsiniz. Dışarıdan almak istediğiniz parametreleri de normal fonksiyon tanımlamalarında olduğu gibi ifade edebilirsiniz. Fonksiyon içerisinde ise Glide işlemlerini tanımlıyoruz. Ayrıca bu fonksiyonu ImageView’a Extension olarak yazdığımız için this ile ImageView’a erişebilirsiniz. Tabii ki BindingAdapter‘ları Extension olarak yazmak bir tercihtir, böyle bir zorunluluk mevcut değil.

Glide, bizim için tanımladığımız URL’den Image‘ı alıp ImageView’da görüntülenmesi için gerekli işlemleri yapıyor. Xml içerisinde “loadImage” ı tanımlayıp alması gereken parametreyi market modelinden karşılıyoruz. Şimdi projemizi çalıştıralım.

Böylelikle URL bağlantısı olan bir resmi ImageView de görüntülemek için Glide kütüphanesini BindingAdapter ile nasıl kurgulayacağımızı görmüş olduk. Bunun gibi farklı amaçlara hizmet eden özel BindingAdapter‘lar tanımlayabilirsiniz.

Şimdi ufak bir göz molası verelim ardından MVVM içerisinde RecyclerView ViewModel ViewState gibi yapılarda DataBinding nasıl bir yer alıyor onları inceleyelim.

Göz molası tamamsa devam edelim.

Şuan yapacağımız 2.projeyi yazının sonundaki Githup reposundan, MVVM-DataBinding branch ‘inden ulaşabilirsiniz.

Market modeli üzerinden devam edeceğiz. Markette yer alan ürünleri listeleyip, detay sayfalarını tasarlayacağız. Home ve Detay sayfası içerisinde LiveData, ViewState gibi konuları işleyeceğiz. Bu işlemleri yaparken belli adımları es geçeceğim. Önceki yazılarımı inceleyebilir veya farklı kaynaklardan o alanda eksikleriniz varsa giderebilirsiniz.

Uygulamamızın HomeFragment’ı için senaryomuz şu şekilde olacak: Ana sayfada marketteki ürünleri listelerken, eğer stok adeti 10 un altında ise, Fiyat bilgisi için 2 farklı değişikliğimiz olacak. Fiyat bilgisi kırmızı renkte ve “%50 indirimli” şeklinde görüntülenecek. Ayrıca item‘ın background‘unun yeşil renkte olmasını istiyoruz.

Peki bu işlemi RecyclerView içerisinde Data Binding kullanarak nasıl kurgulayabiliriz ViewState bu noktada tercih edilebilir. Halil ÖZCAN ’a ViewState konusunda aktardığı bilgiler için teşekkürlerimizi iletmeden geçmeyelim.:)

HomeFragment

Binding ve Adapter tanımlamalarımızı belirtiyoruz . Ayrıca binding’e lifecyclerOwner tanımlarsanız binding’in yaşam döngüsü Fragment’ın yaşam döngüsüne sahip olur.

Market Adapter

Her gelen market modelini MarketViewHolder içerisindeki bind fonksiyonu ile ViewState‘e yönlendiriyoruz. XML’de ise artık market modeli değil ViewState değişkenini oluşturuyoruz. Değer atamaları, renk değişiklikleri, visibility gibi birçok işlemi viewState üzerinden gerçekleştirebiliriz.

ViewState

Senaryoda bahsettiğimiz UI Business Logic‘i kontrol edebilmek için ViewState kullanıyoruz. ViewState, bizlerin market modelini kullanarak veriler üzerinde işlemler yapıp XML içerisindeki component’lere farklı değerlerin gönderilmesi için imkan tanıyor. Senaryomuz dışında UI ile ilgili farklı reaksiyonlar alınacaksa sadece ViewState içerisinde değişiklik yapmamız yeterli olacaktır. Şimdi ise son adım olan XML içerisine bir göz atalım.

Market Item Tasarım

Senaryoda istediğimiz renk değişimini elde etmek için companent’lerde isDiscountColor fonksiyonunu kullanıyoruz. Bu fonksiyon bizlere belirtilen şartlar sağlandığında farklı renk kodlarıyla geri dönüş sağlıyor. tvPrice için ise senaryoda belirtilen şarta göre dönen text değerleri farklılık gösterebiliyor. Diğer component‘lerin text atamaları az önce ifade ettiğimiz örnekteki gibi kullanılıyor

Evet sevgili dostlar yazı biraz uzuyor farkındayım ama gelin son bir konuya daha değinip ardından vedalaşalım. Öncesinde yine ufak bir göz molası verelim..

Şimdi ise şöyle bir senaryo düşünelim: Ürünlere tıklandığında detay sayfamız açılsın ve bu sayfa içerisinde 1 saniyede ürün 5 adet azalsın ve ürün adeti 0 olunca tükendi yazısını görüntüleyelim. Ardından kullanıcı ürün adına basınca ürün adetini yeniden yükleyelim. Ayrıca tüm bu işlemleri ViewModel üzerinden gerçekleştirelim.

ViewModel

Neler yazdık biraz açalım. Market modelimizi XML tarafında işlemek için market adında bir değişken tanımladık.

count ve soldOut değişkenleri LiveData olarak tanımlandı. Bunun nedeni ise bu değişkenlerin değerleri değiştiği zaman XML tarafında otomatik bir şekilde bu değişimin tetiklenmesini istememiz.

minusCount metotu içerisinde her saniyede ürün adetinin 5 azalmasını ve ürün adeti 0 olduğunda tükendi yazısının görüntülenmesini sağlayacak şekilde logic tasarladık.

onClick, ürün adına basıldığında, ürün sayısının yeniden tanımlanması için çağırımlarda bulunduk.

Peki XML tarafında bunu nasıl kurguluyoruz, Hadi şimdi de oraya bir bakalım.

Detay Tasarım

Text‘lerin görüntülenmesi için şimdiye kadar yaptığımız şekilde market model’ine ulaşıp dilediğimiz değerleri görüntülüyoruz. Ekstra olarak count ve price bilgileri için Int-toString dönüşümü gerçekleştirdik.

Tükendi için ivSoldOut ImageView‘ın visibility özelliğine ViewModel içerisindeki soldOut LiveData değerini tanımladık. Böylelikle bu değer her değiştiğinde bu component‘in visibility özelliği de tetiklenecek. Ekstra olarak default gone tanımlamasında bulunduk. Visibility, değer ataması yapabilmek için <data> içerisine view ‘ı import etmeniz gerekmektedir.

tvName, onClick özelliğine ViewModel’da oluşturduğumuz onClick metodunu tanımlıyoruz. Bu metodun view parametresi alması gerektiğini de unutmayalım. Yada “android:onClick="@{() -> viewModel.onClick()}" şeklinde tanımlama yapıp viewModel’daki metodun view parametresini kaldıralım.

Detay Fragment

Detay Fragment içerisinde Data Binding ve ViewModel tanımlamalarını gerçekleştiriyoruz.

Evet dostlar uzun bir yazı oldu fakat konu içerisinde bir çok farklı kullanım olduğu için o alanlara da elimden geldiğince değinmek istedim. Değinmediğim farklı kullanımlar da tabi ki mevcut. Yazmak için değil bilgi aktarımında bulunmak için çabaladım. Umarım faydalı bilgilerde bulunabilmişimdir. Keyifli Kodlamalar..

Dilerseniz DataBinding — Android CodeLab’e buradan ulaşabilirsiniz.

GitHub :

Kaynak :

https://developer.android.com/topic/libraries/data-binding/

https://github.com/CammyKamal/Android-Data-Binding-Examples

Contact :

--

--

Recep Yeşilkaya
Recep Yeşilkaya

No responses yet