Android Kotlin Fundamentals 02.4: Veri bağlama ile ilgili temel bilgiler

Bu codelab, Android Kotlin Temelleri kursuna dahildir. Codelab'ler üzerinden sırayla çalışıyorsanız bu kurstan en iyi şekilde yararlanabilirsiniz. Tüm kurs codelab'leri Android Kotlin Fundamentals codelabs açılış sayfasında listelenmektedir.

Giriş

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

Görünümlerde veri ayarlamak için dize kaynaklarını kullandınız ve etkinlikten gelen verileri ayarladınız. Görüş, verileri bilirse daha verimli olacaktır. Neyse ki bunu yapmak 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 öğrenebilirsiniz.

Bilmeniz gerekenler

Aşağıdaki konular hakkında bilgi sahibi olmalısınız:

  • Etkinlik nedir ve onCreate() içinde düzeni olan bir etkinlik nasıl ayarlanır?
  • Metin görünümü oluşturma ve metin görünümündeki metni ayarlama.
  • Bir görünüme referans almak için findViewById() kullanılıyor.
  • Bir görünüm için temel XML düzeni oluşturma ve düzenleme.

Neler öğreneceksiniz?

  • findViewById() hizmetine 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 özelliğini kullanacak ve verilere doğrudan düzen XML dosyalarından erişecek şekilde değiştirin.

Bu codelab'de, HakkındaMe uygulamasıyla başlar ve uygulamayı veri bağlamayı kullanacak şekilde değiştirirsiniz. İşiniz bittiğinde uygulama tamamen aynı görünecektir.

HakkındaMe uygulamasının işlevi şöyledir:

  • Kullanıcı uygulamayı açtığında, uygulama bir ad, bir takma ad girilecek alan, Bitti düğmesi, yıldız resmi ve kaydırılabilir metin gösterir.
  • Kullanıcı bir 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 HakkındaMeDataLinking-Starter kodunu GitHub'dan indirebilirsiniz.

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

Görünüm oluşturulduktan veya yeniden oluşturulduktan sonra bir görünüm aramak için findViewById() öğesini her kullandığınızda Android sistemi, görünümü bulmak için çalışma zamanında görüntüleme hiyerarşisini doldurur. Uygulamanızın az sayıda görüntüleme alması sorun değildir. Ancak, üretim uygulamalarında bir düzende onlarca görünüm bulunabilir. En iyi tasarıma sahip olsalar bile iç içe yerleştirilmiş görünümler olacaktır.

Metin görünümü içeren kaydırma görünümünü içeren doğrusal bir düzen düşünün. Büyük veya derin görünüm hiyerarşisinde bir görünüm bulmak, kullanıcı için uygulamayı belirgin ölçüde yavaşlatabilecek kadar zaman alabilir. Değişkenlerdeki görünümleri önbelleğe almak size yardımcı olabilir ancak her ad alanında her görünüm için bir değişken başlatmanız gerekir. Çok sayıda görüntüleme ve birden fazla etkinlik olması da bu duruma katkı sağlar.

İyi bir çözüm, her görünüme referans içeren bir nesne oluşturmaktır. Binding nesnesi adı verilen bu nesne, uygulamanızın tamamı tarafından kullanılabilir. Bu teknik, veri bağlama olarak adlandırılır. Uygulamanız için bir bağlayıcı nesne oluşturulduktan sonra, görünüm hiyerarşisinden geçiş yapmak veya verileri aramak zorunda kalmadan görüntüleme nesnesine, bağlama nesnesi aracılığıyla erişebilirsiniz.

Veri bağlama aşağıdaki avantajlara sahiptir:

  • Kod, findByView() kullanan koddan daha kısa, okunması ve bakımı daha kolaydır.
  • Veriler ve görünümler açıkça birbirinden ayrılır. Bu kursun ilerleyen bölümlerinde veri bağlamanın avantajı giderek daha önemli hale gelecek.
  • Android sistemi, her görünümü elde etmek için görüntüleme hiyerarşisinde yalnızca bir kez hareket eder ve kullanıcı uygulamayla etkileşimde bulunduğunda çalışma zamanında değil, uygulama başlatılırken gerçekleşir.
  • Görüntülemelere erişmek için tür güvenliği alırsınız. (Tür güvenliği, derleyicinin derleme sırasında türleri doğruladığı ve bir değişkene yanlış türü atamaya çalıştığınızda hata verdiği anlamına gelir.)

Bu görevde veri bağlamayı ayarlamış olursunuz ve veri bağlamayı, bağlama çağrıları findViewById() nesnesiyle değiştirmek için kullanırsınız.

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

Veri bağlamayı varsayılan olarak etkinleştirmediğinden Gradle dosyanızda veri bağlamayı etkinleştirmeniz gerekir. Bunun nedeni, veri bağlamanın derleme süresini artırmaları ve uygulama başlatma süresini etkilemeleridir.

  1. Önceki bir codelab'den HakkındaMe uygulamanız yoksa GitHub'dan AboutMeDataLinking-Starter kodunu alın. Android Studio'da açın.
  2. build.gradle (Module: app) dosyasını açın.
  3. android bölümünün içine kapatma bölümünden önce bir dataBinding bölümü ekleyin ve enabled öğesini true olarak ayarlayın.
dataBinding {
    enabled = true
}
  1. İstendiğinde projeyi senkronize edin. İstenmezse File > Project Gradle Files ile 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ğlamayla kullanılabilir olacak şekilde değiştirin

Veri bağlamayla çalışmak için XML düzeninizi <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ümleri içeren bir düzen olmasıdır. Bağlama nesnesi, düzeni ve içindeki görünümleri bilebilir.

  1. activity_main.xml dosyasını açın.
  2. Metin sekmesine geçin.
  3. <layout></layout> öğesini <LinearLayout> çevresindeki en dış etiket olarak ekleyin.
<layout>
   <LinearLayout ... >
   ...
   </LinearLayout>
</layout>
  1. Kod girintisini düzeltmek için Kod > Kodu yeniden biçimlendir'i seçin.

    Bir düzenin ad alanı bildirimleri en dış etikette olmalıdır.
  1. Ad alanı beyanlarını <LinearLayout> öğesinden kesip <layout> etiketine yapıştırın. Açılış <layout> etiketiniz aşağıda gösterildiği gibi olmalı ve <LinearLayout> etiketi yalnızca görüntüleme özellikleri içermelidir.
<layout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
  1. İşlemi doğru şekilde yaptığınızdan emin olmak için uygulamanızı oluşturun ve çalıştırın.

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

Ana etkinliğe, bağlama nesnesine bir referans ekleyin. Böylece, görünüme erişmek için bu nesneyi kullanabilirsiniz:

  1. MainActivity.kt dosyasını açın.
  2. onCreate() öğesinden önce, en üst düzeyde bağlama nesnesi için bir değişken oluşturun. Bu değişken normalde binding olarak adlandırılır.

    binding sınıfının (ActivityMainBinding sınıfı) türü, derleyici tarafından özellikle bu ana etkinlik için oluşturulur. Ad, düzen dosyasının adına göre belirlenir: activity_main + Binding.
private lateinit var binding: ActivityMainBinding
  1. Android Studio tarafından istenirse ActivityMainBinding içe aktarın. İstenmiyorsa bu eksik sınıfı içe aktarmak için ActivityMainBinding simgesini ve Alt+Enter düğmesine (Mac'te Option+Enter) basın. (Daha fazla klavye kısayolu için Klavye kısayolları konusuna bakın.)

    import ifadesi aşağıda gösterilene benzemelidir.
import com.example.android.aboutme.databinding.ActivityMainBinding

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

  • Bağlama nesnesini oluşturur.
  • activity_main düzenini MainActivity ile ilişkilendirmek için DataBindingUtil sınıfındaki setContentView() işlevini kullanır. Bu setContentView() işlevi, görünümler için bazı veri bağlama ayarlarını da halleder.
  1. onCreate() içinde 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 aktarın.
import androidx.databinding.DataBindingUtil

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

Artık findViewById() öğesine yapılan tüm çağrıları, bağlayıcı nesnedeki görünüm referanslarıyla 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ı deve durumuna dönüştürür. Dolayısıyla, örneğin bağlama nesnesinde done_button doneButton, nickname_edit nicknameEdit ve nickname_text nicknameText olur.

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

    Şu kodu değiştirin: findViewById<Button>(R.id.done_button)
    şununla değiştirin: binding.doneButton

    onCreate() içinde tıklama dinleyiciyi ayarlamak için kullandığınız kod şu şekilde görünmelidir.
binding.doneButton.setOnClickListener {
   addNickname(it)
}
  1. addNickname() işlevindeki findViewById() öğesine yapılan tüm çağrılar için aynı işlemi yapın.
    findViewById<View>(R.id.id_view) öğesinin tüm geçtiği yerleri binding.idView ile değiştirin. Bunu aşağıdaki şekilde yapın:
  • editText ve nicknameTextView değişkenlerinin tanımlarını ve findViewById() çağrıları Bu işlemde hata alırsınız.
  • Hataları düzeltmek için (silinmiş değişkenler yerine) binding nesnesinden nicknameText, nicknameEdit ve doneButton görünümlerini alın.
  • view.visibility değerini binding.doneButton.visibility ile değiştirin. Girilen view yerine binding.doneButton kodu kullanıldığında kod daha tutarlı hale gelir.

    Sonuç şu koddur:
binding.nicknameText.text = binding.nicknameEdit.text
binding.nicknameEdit.visibility = View.GONE
binding.doneButton.visibility = View.GONE
binding.nicknameText.visibility = View.VISIBLE
  • İşlevsellikte herhangi bir değişiklik yoktur. İsteğe bağlı olarak, artık view parametresini kaldırabilir ve tüm view kullanımını bu işlevin içinde kullanmak için güncelleyebilirsiniz.
  1. nicknameText için String gerekiyor. nicknameEdit.text ise Editable. Veri bağlama kullanırken, Editable öğesini açık bir şekilde String biçimine dönüştürmeniz gerekir.
binding.nicknameText.text = binding.nicknameEdit.text.toString()
  1. Devre dışı bırakılmış içe aktarmaları silebilirsiniz.
  2. apply{} kullanarak işlevi kotele edin.
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ın öncekiyle tam olarak aynı görünmesi ve çalışması gerekir.

Bir veri sınıfının doğrudan görünümde kullanılabilmesi için veri bağlamadan yararlanabilirsiniz. Bu teknik, kodu basitleştirir ve daha karmaşık durumları ele almak açısından çok değerlidir.

Bu örnekte, dize kaynaklarını kullanarak adı ve takma adı ayarlamak yerine, ad ve takma ad için bir veri sınıfı oluşturursunuz. Veri sınıfını kullanarak, veri sınıfını görünümde kullanabilirsiniz.

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

  1. Android dizinindeki java dizininde MyName.kt dosyasını açın. Bu dosyaya sahip değilseniz yeni bir Kotlin dosyası oluşturup MyName.kt dosyasını çağı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 şu anda bir dize kaynağından TextView olarak ayarlanmıştır. Adın referansını, veri sınıfındaki verilere bir referansla değiştirmeniz gerekir.

  1. Metin sekmesinde activity_main.xml uygulamasını açın.
  2. Düzenin üst kısmında <layout> ve <LinearLayout> etiketlerinin arasına bir <data></data> etiketi ekleyin. Görünüm ile veriler arasında bağlantı kurarsınız.
<data>
  
</data>

Veri etiketlerinin içinde, sınıf referansı olan adlandırılmış değişkenleri belirtebilirsiniz.

  1. <data> etiketinin içine bir <variable> etiketi ekleyin.
  2. Değişkene "myName" adı vermek için name parametresi ekleyin. Bir type parametresi ekleyin ve türü, MyName veri sınıfının tam 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şkenini referans alabilirsiniz.

  1. android:text="@string/name" kodunu aşağıdaki kodla değiştirin.

@={}, süslü ayraçların içinde referans alınan verileri almak için kullanılan bir yönergedir.

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

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

3. Adım: Verileri oluşturun

Artık düzen dosyanızdaki verilere referansta bulunuyorsunuz. Ardından asıl verileri oluşturacaksınız.

  1. MainActivity.kt dosyasını açın.
  2. onCreate() üzerinde, kongreye göre 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, az önce bildirdiğiniz myName değişkeninin değerine ayarlayın. Değişkene doğrudan XML'den erişemezsiniz. Dosyaya bağlayıcı nesnesi aracılığıyla erişmeniz gerekir.
binding.myName = myName
  1. Değişiklik yapıldıktan sonra bağlama nesnesini yenilemeniz gerektiğinden bu bir hata gösterebilir. Uygulamanızı geliştirdiğinizde hatanın ortadan kalkmasını sağlayın.

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

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

  1. activity_main.xml'yi açın.
  2. nickname_text metin görünümüne bir text özelliği ekleyin. Aşağıda gösterildiği gibi, veri sınıfındaki nickname öğesine bakın.
android:text="@={myName.nickname}"
  1. ActivityMain içinde rumuzu myName değişkeninde ayarlamak için
    nicknameText.text = nicknameEdit.text.toString()
    yerine kod kullanın.
myName?.nickname = nicknameEdit.text.toString()

Takma ad ayarlandıktan sonra kodunuzun kullanıcı arayüzünü yeni verilerle yenilemesini istersiniz. Bunu yapmak için tüm bağlı ifadeleri, doğru verilerle yeniden oluşturulacak şekilde geçersiz kılmanız gerekir.

  1. Takma adı belirledikten sonra invalidateAll() öğesini, kullanıcı arayüzünün güncellenmiş bağlama nesnesindeki değerle yenilenmesi için ekleyin.
binding.apply {
   myName?.nickname = nicknameEdit.text.toString()
   invalidateAll()
   ...
}
  1. Uygulamanızı oluşturup çalıştırın. Uygulama, öncekiyle aynı şekilde çalışacaktır.

Android Studio projesi: HakkındaMeDataLinking

findViewById() çağrıları yerine 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> kullanın.
  3. Bağlama değişkeni tanımlayın:
    private lateinit var binding: ActivityMainBinding
  4. MainActivity içinde setContentView:
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main) öğesinin yerine başka bir bağlama nesnesi oluşturun
  5. findViewById() öğesine yapılan çağrıları, bağlama nesnesindeki görünüm referanslarıyla değiştirin. Örneğin:
    findViewById<Button>(R.id.done_button) ⇒ binding.doneButoton
    (Örnekte, görünümün adı XML'de görünüm id şeklindedir.)

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> ve veri sınıfı olan bir tür tanımlayın.
<data>
   <variable
       name="myName"
       type="com.example.android.aboutme.MyName" />
</data>
  1. MainActivity öğesinde 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şkene ayarlayın:
    binding.myName = myName
  1. XML'de, görünümün içeriğini <data> blokunda 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 dokümanları:

Bu bölümde, bir eğitmen tarafından sunulan kurs kapsamında bu codelab üzerinden çalışan öğrenciler için olası ev ödevi ödevleri listelenmektedir. Öğretmenin şunları yapması gerekir:

  • Gerekirse ev ödevini atayın.
  • Öğrencilere ev ödevlerinin nasıl gönderileceğini bildirin.
  • Ev ödevlerine not verin.

Öğretmenler bu önerileri istedikleri kadar kullanabilir veya uygun görebilir ve uygun olan diğer ev ödevlerini atayabilirler.

Bu codelab'de kendiniz çalışıyorsanız, bilginizi test etmek için bu ödevlerden yararlanabilirsiniz.

Bu soruları yanıtlayın

1. Soru

findViewById() hesabına yapılan uygunsuz ve üstü kapalı aramaları neden en aza indirmek istiyorsunuz?

  • findViewById() her arandığında, görüntüleme hiyerarşisi değiştirilir.
  • findViewById(), ana veya kullanıcı arayüzü ileti dizisinde çalışıyor.
  • Bu aramalar kullanıcı arayüzünü yavaşlatabilir.
  • Uygulamanızın kilitlenme olasılığı daha düşüktür.

2. Soru

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

Örneğin, veri bağlama hakkında şunları söyleyebilirsiniz:

  • Veri bağlama ile ilgili en büyük fikir, derleme sırasında iki uzak mesafe bilgisini derleyen/eşleyen/bağlayan bir nesne oluşturmaktır. Böylece, çalışma zamanında verileri aramak zorunda kalmazsınız.
  • Bu bağlantıları size bağlayan nesneye bağlama nesnesi adı verilir.
  • Bağlama nesnesi, derleyici tarafından oluşturulur.

3. Soru

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

  • Kod daha kısa, okunması ve bakımı daha kolay.
  • Veriler ve görünümler açıkça birbirinden ayrılır.
  • Android sistemi, her görünümü elde etmek için görüntüleme hiyerarşisinde yalnızca bir kez hareket eder.
  • findViewById() çağrıldığında derleyici hatası oluşturulur.
  • Görünümlere erişmek için yazı güvenliği.

4. Soru

<layout> etiketinin işlevi nedir?

  • İçeriği düzendeki kök görünümünüzün etrafına sarmalarsınız.
  • Bağlamalar, bir düzendeki tüm görünümler için oluşturulur.
  • Üst düzey görünümü, veri bağlama kullanan bir XML düzeninde belirtir.
  • Değişkeni bir veri sınıfına bağlamak için <layout> içindeki <data> etiketini 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 dersi başlatma: 3.1: Parça oluşturma

Bu kurstaki diğer codelab'lerin bağlantılarına ulaşmak için Android Kotlin Fundamentals codelabs açılış sayfasına göz atın.