Android Kotlin Fundamentals 07.2: DiffUtil ve RecyclerView ile veri bağlama

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ş

Bir önceki codelab'de, RecyclerView içerisinde uyku kalitesiyle ilgili verileri göstermek için TrackMySleepquality uygulamasını güncellediniz. İlk RecyclerView'inizi oluştururken öğrendiğiniz teknikler çok büyük olmayan basit listeleri gösteren RecyclerViews çoğu iş için yeterli. Bununla birlikte, RecyclerView'ın büyük listeler için daha verimli olmasını ve karmaşık listeler ve ızgaralar için kodunun korunmasını ve genişletilmesini kolaylaştıran çeşitli teknikler vardır.

Bu codelab'de, önceki codelab'den uyku izleyici uygulamasını temel alırsınız. Uyku verileri listesini güncellemenin daha etkili bir yolunu öğrenin ve RecyclerView ile veri bağlamayı nasıl kullanacağınızı öğrenin. (Uygulamanız önceki codelab'de yoksa, bu codelab için başlangıç kodunu indirebilirsiniz.)

Bilmeniz gerekenler

  • Bir etkinlik, parçalar ve görünümler kullanarak temel kullanıcı arayüzü oluşturma.
  • Parçalar arasında gezinme ve parçaları parçalar arasında aktarmak için safeArgs kullanma.
  • Modelleri görüntüleyin, model fabrikalarını, dönüşümleri, LiveData ve gözlemcilerini görüntüleyin.
  • Room veritabanı oluşturma, DAO oluşturma ve varlıkları tanımlama.
  • Veritabanı ve diğer uzun süreli görevler için eş yordam nasıl kullanılır?
  • Adapter, ViewHolder ve öğe düzeniyle temel bir RecyclerView nasıl uygulanır?

Neler öğreneceksiniz?

  • RecyclerView tarafından görüntülenen bir listeyi etkili bir şekilde güncellemek için DiffUtil nasıl kullanılır?
  • RecyclerView ile veri bağlama nasıl kullanılır?
  • Verileri dönüştürmek için bağlama adaptörlerini kullanma.

Yapacaklarınız

  • Bu serideki önceki codelab'den WatchMySleepquality uygulamasını temel alın.
  • DiffUtil kullanarak listeyi verimli bir şekilde güncellemek için SleepNightAdapter uygulamasını güncelleyin.
  • Verileri dönüştürmek için bağlama adaptörlerini kullanarak RecyclerView için veri bağlama uygulayın.

Uyku izleyici uygulamasında, aşağıdaki resimde gösterildiği gibi parçalarla temsil edilen iki ekran vardır.

Solda gösterilen ilk ekranda izlemeyi başlatmak ve durdurmak için düğmeler bulunur. Ekranda kullanıcının uyku verilerinden bazıları gösterilir. Temizle düğmesi, uygulamanın kullanıcı için topladığı tüm verileri kalıcı olarak siler. Sağ tarafta gösterilen ikinci ekran uyku kalitesi puanı seçmek içindir.

Bu uygulama, uyku verileri sağlamak için bir kullanıcı arayüzü denetleyicisi (ViewModel, LiveData) ve Room veritabanı kullanacak şekilde tasarlanmıştır.

Uyku verileri RecyclerView olarak gösterilir. Bu codelab'de, RecyclerView için DiffUtil ve veri bağlama bölümünü oluşturursunuz. Bu codelab'den sonra uygulamanız tam olarak aynı görünecektir. Ancak ölçeklendirme ve bakımı daha kolay, daha verimli olacaktır.

Önceki codelab'den SleepTracker uygulamasını kullanmaya devam edebilir veya GitHub'dan RecyclerViewDiffUtilDataLinking-Starter uygulamasını indirebilirsiniz.

  1. Gerekirse GitHub'daki RecyclerViewDiffUtilDataBağlaing-Starter uygulamasını indirip Android Studio'da projeyi açın.
  2. Uygulamayı çalıştırın.
  3. SleepNightAdapter.kt dosyasını açın.
  4. Uygulamanın yapısını öğrenmek için kodu inceleyin. Kullanıcıya uyku verilerini göstermek için bağdaştırıcı kalıbıyla RecyclerView kullanımının özetini görmek için aşağıdaki şemaya bakın.

  • Uygulama, kullanıcı girişinden SleepNight nesnelerinin listesini oluşturur. Her SleepNight nesnesi, tek bir uykunun süresini, süresini ve kalitesini temsil eder.
  • SleepNightAdapter, SleepNight nesnelerinin listesini RecyclerView kullanabileceği ve görüntüleyebileceği şekilde uyarlar.
  • SleepNightAdapter adaptörü, verileri görüntülemek için geri dönüşüm görünümünün görünümlerini, verilerini ve meta bilgilerini içeren ViewHolders oluşturur.
  • RecyclerView, kaç öğenin gösterileceğini belirlemek için SleepNightAdapter özelliğini kullanır (getItemCount()). RecyclerView, görüntüleme sahiplerinin görüntüleme için verilerle ilişkilendirilmesini sağlamak için onCreateViewHolder() ve onBindViewHolder() değerlerini kullanır.

NotifyDataSetChanged() yöntemi verimli değil

RecyclerView hizmetine, listedeki bir öğenin değiştiğini ve güncellenmesi gerektiğini bildirmek için mevcut kod, aşağıda gösterildiği gibi SleepNightAdapter içinde notifyDataSetChanged() öğesini çağırır.

var data =  listOf<SleepNight>()
   set(value) {
       field = value
       notifyDataSetChanged()
   }

Ancak notifyDataSetChanged(), RecyclerView adlı kullanıcıya tüm listenin geçersiz olabileceğini bildirir. Sonuç olarak RecyclerView, ekranda görünmeyen öğeler de dahil listedeki her öğeyi bağlayıp yeniden çizer. Bu çok fazla gereksiz bir iş. Büyük veya karmaşık listeler söz konusu olduğunda, kullanıcı listeyi kaydırırken ekran titreşecek veya duraklayacak kadar uzun sürebilir.

Bu sorunu düzeltmek için RecyclerView adlı kullanıcıya tam olarak nelerin değiştiğini söyleyebilirsiniz. RecyclerView, daha sonra yalnızca ekranda değişen görünümleri güncelleyebilir.

RecyclerView, tek bir öğeyi güncellemek için zengin bir API'ye sahiptir. RecyclerView öğesine bir öğenin değiştiğini bildirmek için notifyItemChanged() öğesini kullanabilirsiniz. Ayrıca, eklenen, kaldırılan veya taşınan öğeler için benzer işlevleri kullanabilirsiniz. Hepsini manuel olarak yapabilirsiniz, ancak bu görev kolay olmayacak ve oldukça fazla kod içerebilir.

Neyse ki daha iyi bir yol var.

DiffUtil verimli çalışıyor ve işin zor kısmını yapıyor

RecyclerView, iki liste arasındaki farkları hesaplamak için kullanılan DiffUtil adlı bir sınıfa sahiptir. DiffUtil eski bir listeyi ve yeni bir listeyi alıp farklı olanın ne olduğunu belirler. Eklenen, kaldırılan veya değiştirilen öğeleri bulur. Daha sonra Eugene W. Yeni listeyi oluşturmak için eski listeden yapılacak minimum değişiklik sayısını öğrenmek üzere Myers'ın fark algoritması.

DiffUtilNelerin değiştiğini anladıktan sonra, RecyclerView bu bilgiyi yalnızca değiştirilen, eklenen, kaldırılan veya taşınan öğeleri güncellemek için kullanabilir. Bu da tüm listeyi yeniden yapmaktan çok daha verimlidir.

Bu görevde, RecyclerView'i verilerde yapılacak değişiklikler için optimize etmek üzere DiffUtil'yı kullanmak için SleepNightAdapter'i yükseltirsiniz.

1. Adım: SleepNightDiffCallback uygulayın

DiffUtil sınıfının işlevlerini kullanmak için DiffUtil.ItemCallback süresini uzatın.

  1. SleepNightAdapter.kt'yi açın.
  2. SleepNightAdapter için tam sınıf tanımının altında, SleepNightDiffCallback adında, DiffUtil.ItemCallback süresini kapsayan yeni bir üst sınıf sınıf oluşturun. SleepNight öğesini genel parametre olarak iletin.
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}
  1. İmleci SleepNightDiffCallback sınıf adına yerleştirin.
  2. Alt+Enter (Mac'te Option+Enter ) tuşuna basın ve Üyeleri Uygula'yı seçin.
  3. Açılan iletişim kutusunda, areItemsTheSame() ve areContentsTheSame() yöntemlerini seçmek için üst karakter tuşunu basılı tutarak tıklayın ve ardından Tamam'ı tıklayın.

    Bu işlem, aşağıda gösterildiği gibi iki yöntem için de saplar oluşturur. DiffUtil, listenin ve öğelerin nasıl değiştiğini anlamak için bu iki yöntemi kullanır.
    override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
  1. areItemsTheSame() içinde, TODO öğesinin iletildiği iki oldItem öğesinin (newItem ve newItem) aynı olup olmadığını test eden kodla değiştirin. Öğeler aynı nightId değerine sahipse aynı öğe olduğu için true iade edin. Aksi takdirde false özelliğini iade edin. DiffUtil bu testi kullanarak bir öğenin eklendiğini, kaldırıldığını veya taşındığını keşfedebilir.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
   return oldItem.nightId == newItem.nightId
}
  1. areContentsTheSame() içinde, oldItem ve newItem öğelerinin aynı verileri (yani eşit olup olmadıkları) kontrol edin. SleepNight bir veri sınıfı olduğu için bu eşitlik kontrolü tüm alanları kontrol eder. Data sınıfları sizin için otomatik olarak equals ve diğer birkaç yöntemi tanımlar. oldItem ile newItem arasında farklılıklar varsa bu kod, DiffUtil öğesine öğenin güncellendiğini bildirir.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
   return oldItem == newItem
}

Değişen listelerin gösterilmesi için RecyclerView kullanılması sık karşılaşılan bir kalıptır. RecyclerView, bir listeyle desteklenen bir RecyclerView adaptör oluşturmanıza yardımcı olan bir adaptör sınıfı (ListAdapter) sağlar.

ListAdapter, listeyi sizin için takip eder ve liste güncellendiğinde bağdaştırıcıyı bilgilendirir.

1. Adım: Adaptörünüzü ListAdapter'ı genişletecek şekilde değiştirin

  1. SleepNightAdapter.kt dosyasında, SleepNightAdapter öğesinin sınıf imzasını ListAdapter süresini uzatacak şekilde değiştirin.
  2. İstenirse androidx.recyclerview.widget.ListAdapter öğesini içe aktarın.
  3. SleepNight öğesini ListAdapter öğesinin ilk bağımsız değişkeni olarak ekleyin (SleepNightAdapter.ViewHolder öncesinde).
  4. SleepNightDiffCallback() oluşturucuyu parametre olarak ekleyin. ListAdapter, listede nelerin değiştiğini anlamak için bunu kullanır. Tamamlanan SleepNightAdapter sınıf imzanız aşağıda gösterildiği gibi olmalıdır.
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
  1. SleepNightAdapter sınıfının içindeki data alanını silin. ListAdapter listeyi sizin yerinize takip ettiğinden artık ihtiyacınız yok.
  2. ListAdapter, sizin için bu yöntemi uyguladığından geçersiz kılmayı silin.
  3. onBindViewHolder() hatasını önlemek için item değişkenini değiştirin. item almak için data kodunu kullanmak yerine ListAdapter tarafından sağlanan getItem(position) yöntemini kullanın.
val item = getItem(position)

2. Adım: Listeyi güncel tutmak için sendList() kullanın

Değiştirilen bir liste mevcut olduğunda kodunuzun ListAdapter ile iletişim kurması gerekir. ListAdapter, ListAdapter adlı kullanıcıya listenin yeni bir sürümünün olduğunu bildirmek için submitList() adlı bir yöntem sağlar. Bu yöntem çağrıldığında, ListAdapter yeni listeyi eskisiyle karşılaştırır ve eklenen, kaldırılan, taşınan veya değiştirilen öğeleri algılar. Sonra ListAdapter, RecyclerView tarafından gösterilen öğeleri günceller.

  1. SleepTrackerFragment.kt'yi açın.
  2. onCreateView() içinde, sleepTrackerViewModel konumundaki gözlemcide, sildiğiniz data değişkeninin referans olarak verildiği hatayı bulun.
  3. adapter.data = it numaralı telefonu adapter.submitList(it) adresine bir çağrıyla değiştirin. Güncellenen kod aşağıda gösterilmiştir.

sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
   it?.let {
       adapter.submitList(it)
   }
})
  1. Uygulamanızı çalıştırın. Listeniz küçükse muhtemelen fark edilmeyebilir.

Bu görevde veri bağlamayı ayarlamak için önceki codelab'lerle aynı tekniği kullanır ve findViewById() çağrısını ortadan kaldırırsınız.

1. Adım: Veri bağlamayı düzen dosyasına ekleyin

  1. Metin sekmesinde list_item_sleep_night.xml düzen dosyasını açın.
  2. İmleci ConstraintLayout etiketine yerleştirin ve Alt+Enter (Mac'te Option+Enter tuşuna basın. Niyet menüsü ("hızlı düzeltme" menüsü) açılır.
  3. Veri bağlama düzenine dönüştür'ü seçin. Bu, düzeni <layout> içine alır ve içine <data> etiketi ekler.
  4. Gerekirse en üste geri dönün ve <data> etiketinin içinde sleep adlı bir değişken tanımlayın.
  5. type, SleepNight olan com.example.android.trackmysleepquality.database.SleepNight için tam nitelikli ad olmalıdır. Tamamladığınız <data> etiketi aşağıda gösterildiği gibi olmalıdır.
   <data>
        <variable
            name="sleep"
            type="com.example.android.trackmysleepquality.database.SleepNight"/>
    </data>
  1. Binding nesnesinin oluşturulmasını zorunlu kılmak için Build > Clean Project'i (Projeyi Temizle) ve ardından Build > Project'i Yeniden Oluştur'u seçin. (Sorun yaşamaya devam ederseniz Dosya > Önbellekleri Geçersiz Kıl / Yeniden Başlat'ı seçin.) ListItemSleepNightBinding bağlama nesnesi, ilgili kodla birlikte proje tarafından oluşturulan dosyalara eklenir.

2. Adım: Veri bağlamayı kullanarak öğe düzenini artırın

  1. SleepNightAdapter.kt'yi açın.
  2. ViewHolder sınıfında from() yöntemini bulun.
  3. view değişkeninin beyanını silin.

Silinecek kod:

val view = layoutInflater
       .inflate(R.layout.list_item_sleep_night, parent, false)
  1. view değişkeninin kullanıldığı yerlerde, aşağıda gösterildiği gibi ListItemSleepNightBinding bağlama nesnesini şişiren binding adlı yeni bir değişken tanımlayın. Bağlama nesnesinin gerekli içe aktarımını yapın.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)
  1. İşlevin sonunda, view değerini döndürmek yerine binding değerini döndürün.
return ViewHolder(binding)
  1. Bu hatadan kurtulmak için imlecinizi binding kelimesinin üzerine getirin. Niyet menüsünü açmak için Alt+Enter (Mac'te Option+Enter) tuşuna basın.
  1. 'itemView' sınıfının birincil oluşturucu türünü değiştir 'ViewHolder' to 'ListItemSleepNightLinking' seçeneğini belirleyin. Bu işlem, ViewHolder sınıfının parametre türünü günceller.

  1. İmzada yapılan değişikliği görmek için ViewHolder öğesinin sınıf tanımına gidin. from() yönteminde itemView yöntemini binding olarak değiştirdiğinizden itemView için bir hata görüyorsunuz.

    ViewHolder sınıf tanımında, itemView tekrarından birini sağ tıklayın ve Yeniden değerlendir ve Yeniden adlandır'ı seçin. Adı binding olarak değiştirin.
  2. binding oluşturucu parametresini özellik olarak hazırlamak için val önekini kullanın.
  3. Üst sınıf çağrısında (RecyclerView.ViewHolder) binding olan parametreyi binding.root olarak değiştirin. Bir View iletmeniz gerekir ve binding.root, öğe düzeninizdeki kök ConstraintLayout'dir.
  4. Tamamladığınız sınıf beyanı aşağıdaki koda benzemelidir.
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){

Ayrıca, findViewById() numaralı telefondan gelen aramalar için bir hata görüyorsunuz ve bunu düzeltiyorsunuz.

3. Adım: findViewById() öğesini değiştirin

Artık sleepLength, quality ve qualityImage özelliklerini findViewById() yerine binding nesnesini kullanacak şekilde güncelleyebilirsiniz.

  1. Aşağıda gösterildiği gibi, binding nesnesinin görünümlerini kullanmak için sleepLength, qualityString ve qualityImage başlatmalarını değiştirin. Bundan sonra, kodunuzda başka hata gösterilmez.
val sleepLength: TextView = binding.sleepLength
val quality: TextView = binding.qualityString
val qualityImage: ImageView = binding.qualityImage

Bağlama nesnesi etkinken sleepLength, quality ve qualityImage özelliklerini tanımlamanız gerekmez. DataBinding aramaları önbelleğe alacağından bu özelliklerin belirtilmesine gerek yoktur.

  1. sleepLength, quality ve qualityImage mülk adlarını sağ tıklayın. Yeniden düzenleyin ve Satır içi seçeneğini belirleyin veya Control+Command+N (Mac'te Option+Command+N) tuşuna basın.
  2. Uygulamanızı çalıştırın. (Hata varsa projenizi Temizlemeniz ve Yeniden Derlemeniz gerekebilir.)

Bu görevde, görünümlerinizdeki verileri ayarlamak için uygulamanızı bağlama adaptörleriyle kullanacak şekilde yeni sürüme geçirirsiniz.

Önceki bir codelab'de, LiveData ifadesini almak ve metin görünümlerinde görüntülenecek biçimlendirilmiş dizeler oluşturmak için Transformations sınıfını kullandınız. Ancak farklı türleri veya karmaşık türleri bağlamanız gerekiyorsa veri bağlamanın bu türleri kullanmasına yardımcı olmak için bağlama adaptörleri sağlayabilirsiniz. Bağlama bağdaştırıcıları, verilerinizi alıp veri bağlamanın metin veya resim gibi bir görünümü bağlamak için kullanabileceği bir adaptedir.

Biri kaliteli resim, diğeri de her metin alanı için olmak üzere üç bağlama adaptörü uygulayacaksınız. Özet olarak bir bağlayıcı adaptörü bildirmek için bir öğe ve görünümü alan bir yöntem tanımlar ve buna @BindingAdapter ile ek açıklama eklersiniz. Yöntemin gövdesinde dönüşümü uygularsınız. Kotlin'de, verileri alan görünüm sınıfında, uzantı işlevi olarak bir bağlayıcı adaptörü yazabilirsiniz.

1. Adım: Bağlama adaptörleri oluşturun

  1. SleepNightAdapater.kt'yi açın.
  2. ViewHolder sınıfının içinde bind() yöntemini bulup bu yöntemin işlevini kendinize hatırlatın. binding.sleepLength, binding.quality ve binding.qualityImage için değerleri hesaplayan kodu alıp bunun yerine bağdaştırıcının içinde kullanırsınız. (Şimdilik kodu olduğu gibi bırakın. Daha sonraki bir adımda taşıyacaksınız.)
  3. sleeptracker paketinde, BindingUtils.kt adlı bir dosya oluşturup açın.
  4. TextView adresinde setSleepDurationFormatted adlı bir uzantı işlevi tanımlayın ve bir SleepNight iletin. Bu işlev, uyku süresini hesaplamak ve biçimlendirmek için bağdaştırıcınız olacaktır.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}
  1. setSleepDurationFormatted gövdesinde, verileri ViewHolder.bind() ürününde yaptığınız gibi görünüme bağlayın. convertDurationToFormatted() numaralı telefonu arayıp TextView öğesinin text kısmını biçimlendirilmiş metin olarak ayarlayın. (Bu, TextView üzerindeki bir uzantı işlevi olduğundan doğrudan text özelliğine erişebilirsiniz.)
text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, context.resources)
  1. Bu bağlama adaptörüyle ilgili veri bağlamayı bildirmek için işleve @BindingAdapter ekleyin.
  2. Bu işlev, sleepDurationFormatted özelliğinin adaptörüdür, dolayısıyla @BindingAdapter için bağımsız değişken olarak sleepDurationFormatted değerini iletin.
@BindingAdapter("sleepDurationFormatted")
  1. İkinci adaptör, SleepNight nesnesindeki değere göre uyku kalitesini ayarlar. TextView adresinde setSleepQualityString() adında bir uzantı işlevi oluşturun ve SleepNight parametresi iletin.
  2. Vücutta, verileri ViewHolder.bind() görünümünde yaptığınız gibi görünüme bağlayın. convertNumericQualityToString numaralı telefonu arayıp text özelliğini ayarlayın.
  3. İşlevde @BindingAdapter("sleepQualityString") ile ek açıklama oluşturun.
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight) {
   text = convertNumericQualityToString(item.sleepQuality, context.resources)
}
  1. Üçüncü bağlama adaptörü, resmi bir resim görünümünde ayarlar. ImageView üzerinde uzantı işlevi oluşturun, setSleepImage işlevini çağırın ve aşağıda gösterildiği gibi ViewHolder.bind() kodunu kullanın.
@BindingAdapter("sleepImage")
fun ImageView.setSleepImage(item: SleepNight) {
   setImageResource(when (item.sleepQuality) {
       0 -> R.drawable.ic_sleep_0
       1 -> R.drawable.ic_sleep_1
       2 -> R.drawable.ic_sleep_2
       3 -> R.drawable.ic_sleep_3
       4 -> R.drawable.ic_sleep_4
       5 -> R.drawable.ic_sleep_5
       else -> R.drawable.ic_sleep_active
   })
}

2. Adım: SleepNightAdapter'ı güncelleyin

  1. SleepNightAdapter.kt'yi açın.
  2. bind() yöntemini her şeyi silin. Bunu yapmak için artık veri bağlamayı ve yeni bağdaştırıcılarınızı kullanabilirsiniz.
fun bind(item: SleepNight) {
}
  1. Bağlama nesnesine yeni SleepNight öğeniz hakkında bilgi vermeniz gerektiğinden bind() içinde item uykusunu atayın.
binding.sleep = item
  1. Bu satırın altına binding.executePendingBindings() ekleyin. Bu çağrı, veri bağlamanın beklemede olan bağlamalarını hemen yürütmesini isteyen bir optimizasyondur. RecyclerView içinde bağlayıcı bağdaştırıcıları kullandığınızda executePendingBindings() çağrısı yapmak her zaman iyi bir fikirdir. Çünkü görüntüleme işlemlerini boyutlandırmak biraz daha hızlı olabilir.
 binding.executePendingBindings()

3. Adım: XML düzenine bağlamalar ekleyin

  1. list_item_sleep_night.xml'yi açın.
  2. ImageView varlığında, resmi ayarlayan bağlantı adaptörüyle aynı ada sahip bir app özelliği ekleyin. sleep değişkenini aşağıda gösterildiği gibi iletin.

    Bu özellik, bağdaştırıcı aracılığıyla görünüm ve bağlama nesnesi arasındaki bağlantıyı oluşturur. sleepImage öğesine her başvurulduğunda bağdaştırıcı, SleepNight kapsamındaki verileri uyarlar.
app:sleepImage="@{sleep}"
  1. sleep_length ve quality_string metin görünümleri için aynısını yapın. sleepDurationFormatted veya sleepQualityString öğesine her başvurulduğunda bağdaştırıcılar, SleepNight'daki verileri uyarlar.
app:sleepDurationFormatted="@{sleep}"
app:sleepQualityString="@{sleep}"
  1. Uygulamanızı çalıştırın. Tam olarak öncekiyle aynı şekilde çalışır. Bağlama adaptörleri, veriler değiştikçe görünümleri biçimlendirme ve güncelleme işini üstlenerek ViewHolder işlemini basitleştirir ve koda çok daha iyi bir yapı kazandırır.

Son birkaç egzersiz için aynı listeyi görüntülediniz. Adapter arayüzü, tasarımınızı kodlayarak farklı şekillerde tasarlamanızı sağlar. Kodunuz ne kadar karmaşıksa, doğru şekilde tasarlamanız o kadar önemlidir. Üretim uygulamalarında, bu kalıplar ve diğerleri RecyclerView ile kullanılır. Kalıpların hepsi işe yarar ve her birinin avantajları vardır. Hangisini geliştirmek istediğinize bağlı olarak.

Tebrikler! Bu aşamada, Android'de RecyclerView uzmanlığına ulaşma yolunda ilerliyorsunuz.

Android Studio projesi: RecyclerViewDiffUtilDataLinking.

DiffUtil:

  • RecyclerView, iki liste arasındaki farkları hesaplamak için kullanılan DiffUtil adlı bir sınıfa sahiptir.
  • DiffUtil, iki liste arasındaki farkı anlamak için genişlettiğiniz, ItemCallBack adında bir sınıfa sahiptir.
  • ItemCallback sınıfında areItemsTheSame() ve areContentsTheSame() yöntemlerini geçersiz kılmanız gerekir.

ListAdapter:

  • Liste yönetimini ücretsiz olarak almak için RecyclerView.Adapter yerine ListAdapter sınıfını kullanabilirsiniz. Ancak, ListAdapter kullanıyorsanız diğer düzenler için kendi bağdaştırıcınızı yazmanız gerekir. Bu nedenle, bu codelab'de bunu nasıl yapacağınız gösterilmektedir.
  • Android Studio'da intent menüsünü açmak için imleci herhangi bir kod öğesine getirin ve Alt+Enter (Mac'te Option+Enter) tuşuna basın. Bu menü, kodu yeniden düzenlemek ve yöntem uygulamak için saplamalar oluşturmak açısından özellikle faydalıdır. Menü, bağlama duyarlıdır. Bu nedenle, doğru menüyü almak için imleci tam olarak yerleştirmeniz gerekir.

Veri bağlama:

  • Verileri görünümlere bağlamak için öğe düzeninde veri bağlama kullanın.

Bağlama adaptörleri:

  • Daha önce verilerden dizeler oluşturmak için Transformations kullandınız. Farklı veya karmaşık türdeki verileri bağlamanız gerekiyorsa veri bağlamanın bunları kullanmasına yardımcı olmak için bağlama adaptörleri sağlayın.
  • Bağlama adaptörünü bildirmek için bir öğe ve görünümü alan bir yöntem tanımlayın ve bu yönteme @BindingAdapter ekleyin. Kotlin'de bağlayıcı adaptörünü View üzerinde uzantı işlevi olarak yazabilirsiniz. Adaptörün uyarladığı mülkün adını iletin. Örneğin:
@BindingAdapter("sleepDurationFormatted")
  • XML düzeninde, bağlama adaptörüyle aynı ada sahip bir app özelliği ayarlayın. Verileri içeren bir değişken iletin. Örneğin:
.app:sleepDurationFormatted="@{sleep}"

Udacity kursları:

Android geliştirici dokümanları:

Diğer kaynaklar:

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

Aşağıdakilerden hangisi DiffUtil özelliğini kullanmak için gereklidir? Geçerli olan tüm seçenekleri işaretleyin.

ItemCallBack sınıfını genişletin.

areItemsTheSame() adlı alanı geçersiz kıl.

areContentsTheSame() adlı alanı geçersiz kıl.

▢ Öğeler arasındaki farkları izlemek için veri bağlamayı kullanın.

2. Soru

Bağlama adaptörleriyle ilgili olarak aşağıdakilerden hangisi doğrudur?

▢ Bağlayıcı adaptörü, @BindingAdapter ile açıklama eklenen bir işlevdir.

▢ Bağlama adaptörünü kullanmak, veri biçimlendirmesini görünüm sahibinden ayırmanızı sağlar.

▢ Bağdaştırıcı kullanmak istiyorsanız bir RecyclerViewAdapter kullanmanız gerekir.

▢ Bağlama adaptörleri, karmaşık verileri dönüştürmeniz gerektiğinde iyi bir çözümdür.

3. Soru 3

Bağlama adaptörü yerine Transformations kullanmayı ne zaman düşünmelisiniz? Geçerli olan tüm seçenekleri işaretleyin.

▢ Verileriniz basittir.

▢ Bir dizeyi biçimlendiriyorsunuz.

▢ Listeniz çok uzun.

ViewHolder yalnızca bir görünüm içerir.

Sonraki derse başlayın: 7.3: RecyclerView ile LayoutLayout