Android Kotlin Hakkında Temel Bilgiler 02.4: Veri bağlamayla ilgili temel bilgiler

Bu codelab, Android Kotlin Hakkında Temel Bilgiler kursunun bir parçasıdır. Bu kurstan en iyi şekilde yararlanmak için codelab'leri sırayla tamamlamanızı öneririz. Kursla ilgili tüm codelab'ler Android Kotlin Hakkında Temel Bilgiler codelab'leri açılış sayfasında listelenir.

Giriş

Bu kurstaki önceki codelab'lerde, görünümlere referans almak için findViewById() işlevini kullandınız. Uygulamanızda karmaşık görünüm hiyerarşileri olduğunda findViewById() pahalıdır ve uygulamayı yavaşlatır. Bunun nedeni, Android'in görünüm hiyerarşisini kökten başlayarak istenen görünümü bulana kadar geçmesidir. Neyse ki daha iyi bir yol var.

Görünümlerde veri ayarlamak için dize kaynaklarını kullandınız ve etkinlikten verileri ayarladınız. Görünümün veriler hakkında bilgi sahibi olması daha verimli olur. Neyse ki bu da mümkün.

Bu codelab'de, findViewById() ihtiyacını ortadan kaldırmak için veri bağlamayı nasıl kullanacağınızı öğreneceksiniz. Ayrıca, verilere doğrudan bir görünümden erişmek için veri bağlamayı nasıl kullanacağınızı da öğreneceksiniz.

Bilmeniz gerekenler

Aşağıdaki konular hakkında bilgi sahibi olmanız gerekir:

  • Etkinlik nedir ve onCreate()'da düzen içeren bir etkinlik nasıl oluşturulur?
  • Metin görünümü oluşturma ve metin görünümünde gösterilen metni ayarlama.
  • Görünüme referans almak için findViewById() kullanma.
  • Görünüm için temel bir XML düzeni oluşturma ve düzenleme.

Neler öğreneceksiniz?

  • findViewById()'ya yapılan verimsiz çağrıları ortadan kaldırmak için Veri Bağlama Kitaplığı'nı kullanma
  • Uygulama verilerine doğrudan XML'den erişme

Yapacaklarınız

  • Bir uygulamayı findViewById() yerine veri bağlama kullanacak ve verilere doğrudan düzen XML dosyalarından erişecek şekilde değiştirin.

Bu codelab'de AboutMe uygulamasıyla başlayıp uygulamayı veri bağlama kullanacak şekilde değiştireceksiniz. İşlemi tamamladığınızda uygulama tam olarak aynı görünecek.

Hakkımda uygulaması şunları yapar:

  • Kullanıcı uygulamayı açtığında uygulamada bir ad, takma ad girilecek bir alan, Bitti düğmesi, yıldız resmi ve kaydırılabilir metin gösterilir.
  • Kullanıcı, takma ad girip Bitti düğmesine dokunabilir. Düzenlenebilir alan ve düğme, girilen takma adı gösteren bir metin görünümüyle değiştirilir.


Önceki codelab'de oluşturduğunuz kodu kullanabilir veya GitHub'dan AboutMeDataBinding-Starter kodunu indirebilirsiniz.

Önceki codelab'lerde yazdığınız kod, görünümlere referans almak için findViewById() işlevini kullanır.

Bir görünüm oluşturulduktan veya yeniden oluşturulduktan sonra görünümü aramak için her findViewById() kullandığınızda Android sistemi, görünümü bulmak için çalışma zamanında görünüm hiyerarşisinde gezinir. Uygulamanızın görüntülenme sayısı az olduğunda bu bir sorun değildir. Ancak üretim uygulamalarında bir düzende düzinelerce görünüm olabilir ve en iyi tasarımla bile iç içe yerleştirilmiş görünümler olacaktır.

Bir metin görünümü içeren kaydırma görünümü içeren doğrusal bir düzen düşünün. Büyük veya derin bir görünüm hiyerarşisinde bir görünümü bulmak, uygulamanın kullanıcı için belirgin şekilde yavaşlamasına neden olacak kadar uzun sürebilir. Görünümleri değişkenlerde önbelleğe almak yardımcı olabilir ancak yine de her görünüm için her ad alanında bir değişken başlatmanız gerekir. Çok sayıda görüntüleme ve birden fazla etkinlik olduğunda bu da artar.

Bir çözüm, her görünüme referans içeren bir nesne oluşturmaktır. Binding nesnesi olarak adlandırılan bu nesne, uygulamanızın tamamı tarafından kullanılabilir. Bu tekniğe veri bağlama adı verilir. Uygulamanız için bir bağlama nesnesi oluşturulduktan sonra, görünüm hiyerarşisinde gezinmeniz veya verileri aramanız gerekmeden bağlama nesnesi aracılığıyla görünümlere ve diğer verilere erişebilirsiniz.

Veri bağlamanın aşağıdaki avantajları vardır:

  • findByView() kullanılan kodlara kıyasla daha kısa, okunması ve bakımı daha kolaydır.
  • Veriler ve görünümler net bir şekilde ayrılır. Veri bağlamanın bu avantajı, bu kursun ilerleyen bölümlerinde daha da önem kazanacaktır.
  • Android sistemi, her görünümü almak için görünüm hiyerarşisini yalnızca bir kez geçer. Bu işlem, uygulamanın başlatılması sırasında gerçekleşir ve kullanıcı uygulamayla etkileşimde bulunurken çalışma zamanında gerçekleşmez.
  • Görünümlere erişmek için tür güvenliği elde edersiniz. (Tür güvenliği, derleyici derleme sırasında türleri doğrular ve bir değişkene yanlış tür atamaya çalışırsanız hata verir.)

Bu görevde veri bağlamayı ayarlayacak ve findViewById() çağrılarını bağlama nesnesine yapılan çağrılarla değiştirmek için veri bağlamayı kullanacaksınız.

1. adım: Veri bağlamayı etkinleştirin

Veri bağlamayı kullanmak için Gradle dosyanızda veri bağlamayı etkinleştirmeniz gerekir. Bu özellik varsayılan olarak etkin değildir. Bunun nedeni, veri bağlamanın derleme süresini artırması ve uygulamanın başlatılma süresini etkileyebilmesidir.

  1. Önceki bir codelab'den AboutMe uygulamanız yoksa GitHub'dan AboutMeDataBinding-Starter kodunu alın. Android Studio'da açın.
  2. build.gradle (Module: app) dosyasını açın.
  3. Kapatma ayracından önce android bölümünün içine bir dataBinding bölümü ekleyin ve enabled değerini true olarak ayarlayın.
dataBinding {
    enabled = true
}
  1. İstendiğinde projeyi senkronize edin. İstem almazsanız Dosya > Projeyi Gradle Dosyalarıyla Senkronize Et'i seçin.
  2. Uygulamayı çalıştırabilirsiniz ancak herhangi bir değişiklik görmezsiniz.

2. adım: Düzen dosyasını veri bağlama ile kullanılabilir hale getirin

Veri bağlama ile çalışmak için XML düzeninizi bir <layout> etiketiyle sarmalamanız gerekir. Bunun nedeni, kök sınıfın artık bir görünüm grubu değil, görünüm grupları ve görünümler içeren bir düzen olmasıdır. Bağlama nesnesi, düzen ve içindeki görünümler hakkında bilgi sahibi olabilir.

  1. activity_main.xml dosyasını açın.
  2. Metin sekmesine geçin.
  3. <layout></layout> etiketini <LinearLayout> etiketinin en dışına ekleyin.
<layout>
   <LinearLayout ... >
   ...
   </LinearLayout>
</layout>
  1. Kod girintisini düzeltmek için Code > Reformat code (Kod > Kodu yeniden biçimlendir) seçeneğini belirleyin.

    Bir düzenin ad alanı beyanları en dıştaki etikette olmalıdır.
  1. Ad alanı beyanlarını <LinearLayout> etiketinden kesin ve <layout> etiketine yapıştırın. Açılış <layout> etiketiniz aşağıda gösterildiği gibi görünmeli ve <LinearLayout> etiketi yalnızca görünüm özelliklerini içermelidir.
<layout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
  1. Bu işlemi doğru şekilde yaptığınızı doğrulamak için uygulamanızı derleyip çalıştırın.

3. adım: Ana etkinlikte bir bağlama nesnesi oluşturun

Görünümlere erişmek için kullanabilmeniz amacıyla bağlama nesnesine ana etkinlikte bir referans ekleyin:

  1. MainActivity.kt dosyasını açın.
  2. onCreate()'dan önce, en üst düzeyde bağlama nesnesi için bir değişken oluşturun. Bu değişkene genellikle binding adı verilir.

    binding türü olan ActivityMainBinding sınıfı, derleyici tarafından özellikle bu ana etkinlik için oluşturulur. Ad, düzen dosyasının adından (activity_main + Binding) türetilir.
private lateinit var binding: ActivityMainBinding
  1. Android Studio tarafından istenirse ActivityMainBinding içe aktarın. İstem almazsanız ActivityMainBinding simgesini tıklayın ve bu eksik sınıfı içe aktarmak için Alt+Enter tuşuna (Mac'te Option+Enter) basın. (Diğer klavye kısayolları için Klavye kısayolları başlıklı makaleyi inceleyin.)

    import ifadesi, aşağıda gösterilene benzer olmalıdır.
import com.example.android.aboutme.databinding.ActivityMainBinding

Ardından, mevcut setContentView() işlevini aşağıdaki işlemleri yapan bir talimatla değiştirirsiniz:

  • Bağlama nesnesini oluşturur.
  • setContentView() işlevini kullanarak DataBindingUtil sınıfından activity_main düzenini MainActivity ile ilişkilendirir. Bu setContentView() işlevi, görünümler için bazı veri bağlama kurulumlarını da gerçekleştirir.
  1. onCreate() bölümünde, setContentView() çağrısını aşağıdaki kod satırıyla değiştirin.
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
  1. DataBindingUtil içe aktarın.
import androidx.databinding.DataBindingUtil

4. adım: findViewById() işlevine yapılan tüm çağrıları değiştirmek için bağlama nesnesini kullanın

Artık findViewById() ile yapılan tüm çağrıları bağlama nesnesindeki görünümlere yapılan referanslarla değiştirebilirsiniz. Bağlama nesnesi oluşturulduğunda derleyici, bağlama nesnesindeki görünümlerin adlarını düzendeki görünümlerin kimliklerinden oluşturur ve bunları camel case'e dönüştürür. Örneğin, done_button bağlama nesnesinde doneButton, nickname_edit nicknameEdit ve nickname_text nicknameText olur.

  1. onCreate() içinde, done_button öğesini bulmak için findViewById() kullanan kodu, bağlama nesnesindeki düğmeye referans veren kodla değiştirin.

    Bu kodu: findViewById<Button>(R.id.done_button)
    ile değiştirin: binding.doneButton

    Tıklama işleyicisini onCreate() içinde ayarlamak için tamamlanmış kodunuz aşağıdaki gibi görünmelidir.
binding.doneButton.setOnClickListener {
   addNickname(it)
}
  1. addNickname() işlevindeki tüm findViewById() aramaları için de aynı işlemi yapın.
    findViewById<View>(R.id.id_view) öğesinin tüm örneklerini binding.idView ile değiştirin. Bu işlemi aşağıdaki şekilde yapın:
  • editText ve nicknameTextView değişkenlerinin tanımlarını findViewById() çağrılarıyla birlikte silin. Bu işlem hatalara neden olur.
  • nicknameText, nicknameEdit ve doneButton görünümlerini (silinmiş) değişkenler yerine binding nesnesinden alarak hataları düzeltin.
  • view.visibility yerine binding.doneButton.visibility koyun. view yerine binding.doneButton kullanmak kodu daha tutarlı hale getirir.

    Sonuç aşağıdaki koddur:
binding.nicknameText.text = binding.nicknameEdit.text
binding.nicknameEdit.visibility = View.GONE
binding.doneButton.visibility = View.GONE
binding.nicknameText.visibility = View.VISIBLE
  • İşlevlerde değişiklik yapılmadı. İsteğe bağlı olarak, artık view parametresini kaldırabilir ve bu işlevde view kullanımının tümünü binding.doneButton kullanacak şekilde güncelleyebilirsiniz.
  1. nicknameText için String gerekir ve nicknameEdit.text, Editable'dir. Veri bağlama kullanılırken Editable öğesinin açıkça String öğesine dönüştürülmesi gerekir.
binding.nicknameText.text = binding.nicknameEdit.text.toString()
  1. Gri renkteki içe aktarımları silebilirsiniz.
  2. apply{} kullanarak işlevi Kotlin'e dönüştürün.
binding.apply {
   nicknameText.text = nicknameEdit.text.toString()
   nicknameEdit.visibility = View.GONE
   doneButton.visibility = View.GONE
   nicknameText.visibility = View.VISIBLE
}
  1. Uygulamanızı derleyip çalıştırın. Uygulamanız, eskisiyle tamamen aynı şekilde görünmeli ve çalışmalıdır.

Veri sınıfını doğrudan bir görünümde kullanılabilir hale getirmek için veri bağlamadan yararlanabilirsiniz. Bu teknik, kodu basitleştirir ve daha karmaşık durumları ele almak için son derece değerlidir.

Bu örnekte, adı ve takma adı dize kaynaklarını kullanarak ayarlamak yerine ad ve takma ad için bir veri sınıfı oluşturursunuz. Veri bağlama özelliğini kullanarak veri sınıfını görünümde kullanılabilir hale getirirsiniz.

1. adım: MyName veri sınıfını oluşturun

  1. Android Studio'da java dizinindeki MyName.kt dosyasını açın. Bu dosyanız yoksa yeni bir Kotlin dosyası oluşturup MyName.kt olarak adlandırın.
  2. Ad ve takma ad için bir veri sınıfı tanımlayın. Varsayılan değer olarak boş dizeler kullanın.
data class MyName(var name: String = "", var nickname: String = "")

2. adım: Düzene veri ekleyin

activity_main.xml dosyasında ad, dize kaynağındaki TextView olarak ayarlanmış. Ad referansını, veri sınıfındaki verilere yönelik bir referansla değiştirmeniz gerekir.

  1. activity_main.xml dosyasını Metin sekmesinde açın.
  2. Düzenin en üstünde, <layout> ve <LinearLayout> etiketleri arasına bir <data></data> etiketi ekleyin. Görünümü verilerle burada bağlarsınız.
<data>
  
</data>

Veri etiketlerinin içinde, bir sınıfa referans tutan adlandırılmış değişkenler bildirebilirsiniz.

  1. <data> etiketinin içine bir <variable> etiketi ekleyin.
  2. Değişkene "myName" adını vermek için name parametresini ekleyin. type parametresi ekleyin ve türü MyName veri sınıfının tam nitelikli adı (paket adı + değişken adı) olarak ayarlayın.
<variable
       name="myName"
       type="com.example.android.aboutme.MyName" />

Artık ad için dize kaynağını kullanmak yerine myName değişkenine referans verebilirsiniz.

  1. android:text="@string/name" yerine aşağıdaki kodu girin.

@={}, küme parantezleri içinde referans verilen verileri almak için kullanılan bir yönergedir.

myName, daha önce tanımladığınız myName değişkenine referans verir. Bu değişken, myName veri sınıfına işaret eder ve sınıftan name özelliğini getirir.

android:text="@={myName.name}"

3. adım: Verileri oluşturun

Artık düzen dosyanızdaki verilere referansınız var. Ardından, gerçek verileri oluşturursunuz.

  1. MainActivity.kt dosyasını açın.
  2. onCreate() üstünde, geleneksel olarak myName olarak da adlandırılan özel bir değişken oluşturun. Değişkene, adı ileterek MyName veri sınıfının bir örneğini atayın.
private val myName: MyName = MyName("Aleks Haecky")
  1. onCreate() içinde, düzen dosyasındaki myName değişkeninin değerini, yeni tanımladığınız myName değişkeninin değerine ayarlayın. Değişkene doğrudan XML'den erişemezsiniz. Bağlama nesnesi üzerinden erişmeniz gerekir.
binding.myName = myName
  1. Değişiklik yaptıktan sonra bağlama nesnesini yenilemeniz gerektiğinden bu işlem hata gösterebilir. Uygulamanızı oluşturduğunuzda hata ortadan kalkar.

4. adım: TextView'daki takma ad için veri sınıfını kullanın

Son adım, TextView içindeki takma ad için de veri sınıfını kullanmaktır.

  1. activity_main.xml adlı kişiyi aç.
  2. nickname_text metin görünümünde text özelliği ekleyin. Aşağıda gösterildiği gibi veri sınıfındaki nickname öğesini referans alın.
android:text="@={myName.nickname}"
  1. ActivityMain bölümünde,
    nicknameText.text = nicknameEdit.text.toString()
    yerine myName değişkeninde takma adı ayarlayacak kodu girin.
myName?.nickname = nicknameEdit.text.toString()

Takma ad ayarlandıktan sonra kodunuzun kullanıcı arayüzünü yeni verilerle yenilemesini istiyorsunuz. Bunun için tüm bağlama ifadelerini geçersiz kılmanız gerekir. Böylece, ifadeler doğru verilerle yeniden oluşturulur.

  1. Takma adı ayarladıktan sonra invalidateAll() ekleyin. Böylece kullanıcı arayüzü, güncellenen bağlama nesnesindeki değerle yenilenir.
binding.apply {
   myName?.nickname = nicknameEdit.text.toString()
   invalidateAll()
   ...
}
  1. Uygulamanızı derleyip çalıştırın. Uygulamanız eskisi gibi çalışmaya devam eder.

Android Studio projesi: AboutMeDataBinding

findViewById() işlevine yapılan çağrıları değiştirmek için veri bağlamayı kullanma adımları:

  1. build.gradle dosyasının android bölümünde veri bağlamayı etkinleştirin:
    dataBinding { enabled = true }
  2. XML düzeninizde kök görünüm olarak <layout> öğesini kullanın.
  3. Bir bağlama değişkeni tanımlayın:
    private lateinit var binding: ActivityMainBinding
  4. MainActivity içinde bir bağlama nesnesi oluşturun ve setContentView yerine
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main) yazın.
  5. findViewById() çağrılarını bağlama nesnesindeki görünüm referanslarıyla değiştirin. Örneğin:
    findViewById<Button>(R.id.done_button) ⇒ binding.doneButton
    (Örnekte, görünümün adı XML'deki görünümün id öğesinden deve harfiyle oluşturulur.)

Görünümleri verilere bağlama adımları:

  1. Verileriniz için bir veri sınıfı oluşturun.
  2. <layout> etiketinin içine bir <data> bloğu ekleyin.
  3. Bir <variable> tanımlayın. Bu <variable>'nın adı ve veri sınıfı olan bir türü olmalıdır.
<data>
   <variable
       name="myName"
       type="com.example.android.aboutme.MyName" />
</data>
  1. MainActivity içinde, veri sınıfının bir örneğini içeren bir değişken oluşturun. Örneğin:
    private val myName: MyName = MyName("Aleks Haecky")
  1. Bağlama nesnesinde değişkeni, yeni oluşturduğunuz değişken olarak ayarlayın:
    binding.myName = myName
  1. XML'de, görünümün içeriğini <data> bloğunda tanımladığınız değişkene ayarlayın. Veri sınıfının içindeki verilere erişmek için nokta gösterimini kullanın.
    android:text="@={myName.name}"

Udacity kursu:

Android geliştirici belgeleri:

Bu bölümde, bir eğitmenin yönettiği kurs kapsamında bu codelab'i tamamlayan öğrenciler için olası ödevler listelenmektedir. Eğitmen, aşağıdakileri yapmalıdır:

  • Gerekirse ödev atayın.
  • Öğrencilere ev ödevi ödevlerini nasıl göndereceklerini bildirin.
  • Ödevlere not verin.

Eğitmenler bu önerileri istedikleri kadar kullanabilir ve uygun olduğunu düşündükleri diğer ödevleri verebilirler.

Bu codelab'i kendi başınıza tamamlıyorsanız bilginizi test etmek için bu ödevleri kullanabilirsiniz.

Bu soruları yanıtlayın

1. Soru

Neden findViewById() için açık ve örtülü çağrıları en aza indirmek istiyorsunuz?

  • findViewById() her çağrıldığında görünüm hiyerarşisinde gezinir.
  • findViewById(), ana iş parçacığında veya kullanıcı arayüzü iş parçacığında çalışır.
  • Bu aramalar, kullanıcı arayüzünü yavaşlatabilir.
  • Uygulamanızın kilitlenme olasılığı azalır.

2. Soru

Veri bağlamayı nasıl tanımlarsınız?

Örneğin, veri bağlama hakkında söyleyebileceğiniz bazı şeyler:

  • Veri bağlama ile ilgili temel fikir, derleme zamanında iki uzak bilgi parçasını birbirine bağlayan/eşleyen/bağlayan bir nesne oluşturmaktır. Böylece, çalışma zamanında verileri aramanız gerekmez.
  • Bu bağlamaları size sunan nesneye bağlama nesnesi denir.
  • Bağlama nesnesi derleyici tarafından oluşturulur.

3. Soru

Aşağıdakilerden hangisi veri bağlamanın avantajlarından DEĞİLDİR?

  • Kod daha kısa, okunması daha kolay ve bakımı daha kolaydır.
  • Veriler ve görünümler net bir şekilde ayrılır.
  • Android sistemi, her görünümü almak için görünüm hiyerarşisinde yalnızca bir kez gezinir.
  • findViewById() işlevini çağırmak derleyici hatası oluşturur.
  • Görünümlere erişmek için tür güvenliği.

4. Soru

<layout> etiketinin işlevi nedir?

  • Düzeninizdeki kök görünümün etrafına sarmalarsınız.
  • Bir düzendeki tüm görünümler için bağlamalar oluşturulur.
  • Veri bağlama kullanan bir XML düzenindeki üst düzey görünümü belirtir.
  • Bir değişkeni bir veri sınıfına bağlamak için <data> etiketini <layout> içinde kullanabilirsiniz.

5. Soru

XML düzeninde bağlı verilere referans vermenin doğru yolu hangisidir?

  • android:text="@={myDataClass.property}"
  • android:text="@={myDataClass}"
  • android:text="@={myDataClass.property.toString()}"
  • android:text="@={myDataClass.bound_data.property}"

Sonraki derse başlayın: 3.1: Parça oluşturma

Bu kurstaki diğer codelab'lerin bağlantılarını Android Kotlin Hakkında Temel Bilgiler codelab'leri açılış sayfasında bulabilirsiniz.