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ş
Önceki codelab'de TrackMySleepQuality uygulamasını, uyku kalitesiyle ilgili verileri RecyclerView
içinde gösterecek şekilde güncellemiştiniz. İlk RecyclerView
'nizi oluştururken öğrendiğiniz teknikler, çok büyük olmayan basit listeler gösteren çoğu RecyclerViews
için yeterlidir. Ancak, RecyclerView
'yı büyük listeler için daha verimli hale getiren ve kodunuzun karmaşık listeler ve ızgaralar için bakımını ve genişletilmesini kolaylaştıran bir dizi teknik vardır.
Bu codelab'de, önceki codelab'deki uyku izleme uygulamasını temel alacaksınız. Uyku verileri listesini güncellemenin daha etkili bir yolunu ve RecyclerView
ile veri bağlamayı nasıl kullanacağınızı öğrenirsiniz. (Önceki codelab'den uygulamayı kullanmıyorsanız bu codelab'in başlangıç kodunu indirebilirsiniz.)
Bilmeniz gerekenler
- Etkinlik, parçalar ve görünümler kullanarak temel bir kullanıcı arayüzü oluşturma.
- Parçalar arasında gezinme ve parçalar arasında veri aktarmak için
safeArgs
kullanma. - Modelleri, model fabrikalarını, dönüşümleri ve
LiveData
ile gözlemcilerini görüntüleyin. Room
veritabanı oluşturma, DAO oluşturma ve varlıkları tanımlama- Veritabanı ve diğer uzun süren görevler için eş yordamları kullanma
Adapter
,ViewHolder
ve öğe düzeniyle temel birRecyclerView
nasıl uygulanır?
Neler öğreneceksiniz?
DiffUtil
kullanarakRecyclerView
tarafından gösterilen bir listeyi nasıl verimli bir şekilde güncelleyebilirsiniz?RecyclerView
ile veri bağlamayı kullanma- Verileri dönüştürmek için bağlama adaptörlerini kullanma
Yapacaklarınız
- Bu serideki önceki codelab'de yer alan TrackMySleepQuality uygulamasını temel alın.
DiffUtil
kullanarak listeyi verimli bir şekilde güncellemek içinSleepNightAdapter
simgesini güncelleyin.- Verileri dönüştürmek için bağlama adaptörlerini kullanarak
RecyclerView
için veri bağlamayı uygulayın.
Uyku izleme uygulamasının, aşağıdaki şekilde gösterildiği gibi parçalarla temsil edilen iki ekranı vardır.
Solda gösterilen ilk ekranda izlemeyi başlatma ve durdurma düğmeleri 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ğda gösterilen ikinci ekranda uyku kalitesi derecesi seçilir.
Bu uygulama, uyku verilerini kalıcı hale getirmek için kullanıcı arayüzü denetleyicisi, ViewModel
ve LiveData
ile Room
veritabanı kullanacak şekilde tasarlanmıştır.
Uyku verileri RecyclerView
olarak gösterilir. Bu codelab'de, DiffUtil
ve RecyclerView
için veri bağlama bölümünü oluşturacaksınız. Bu codelab'den sonra uygulamanızın görünümü değişmeyecek ancak daha verimli, ölçeklendirmesi ve bakımı daha kolay olacak.
Önceki codelab'deki SleepTracker uygulamasını kullanmaya devam edebilir veya GitHub'dan RecyclerViewDiffUtilDataBinding-Starter uygulamasını indirebilirsiniz.
- Gerekirse GitHub'dan RecyclerViewDiffUtilDataBinding-Starter uygulamasını indirip projeyi Android Studio'da açın.
- Uygulamayı çalıştırın.
SleepNightAdapter.kt
dosyasını açın.- Uygulamanın yapısını öğrenmek için kodu inceleyin. Kullanıcıya uyku verilerini göstermek üzere bağdaştırıcı deseniyle
RecyclerView
kullanmanın özeti için aşağıdaki şemaya bakın.
- Uygulama, kullanıcı girişinden
SleepNight
nesnelerin listesini oluşturur. HerSleepNight
nesnesi, tek bir gece uykusunu, süresini ve kalitesini temsil eder. SleepNightAdapter
,SleepNight
nesnelerinin listesiniRecyclerView
tarafından kullanılabilecek ve görüntülenebilecek bir şeye dönüştürür.SleepNightAdapter
bağdaştırıcısı, 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çerenViewHolders
oluşturur.RecyclerView
, görüntülenecek öğe sayısını belirlemek içinSleepNightAdapter
kullanır (getItemCount()
).RecyclerView
, görüntüleme tutucuları görüntüleme için verilere bağlamak üzereonCreateViewHolder()
veonBindViewHolder()
kullanır.
notifyDataSetChanged() yöntemi verimsizdir
Listedeki bir öğenin değiştiğini ve güncellenmesi gerektiğini RecyclerView
öğesine bildirmek için mevcut kod, aşağıdaki örnekte gösterildiği gibi SleepNightAdapter
içinde notifyDataSetChanged()
öğesini çağırır.
var data = listOf<SleepNight>()
set(value) {
field = value
notifyDataSetChanged()
}
Ancak notifyDataSetChanged()
, RecyclerView
'ye listenin tamamının geçersiz olabileceğini bildirir. Sonuç olarak, RecyclerView
ekranda görünür olmayan öğeler de dahil olmak üzere listedeki her öğeyi yeniden bağlar ve yeniden çizer. Bu, çok fazla gereksiz işe yol açar. Büyük veya karmaşık listelerde bu işlem, kullanıcının listede gezinirken ekranın titremesine veya takılmasına neden olacak kadar uzun sürebilir.
Bu sorunu düzeltmek için RecyclerView
'a tam olarak neyin değiştiğini söyleyebilirsiniz. RecyclerView
daha sonra ekranda değişen görünümleri güncelleyebilir.
RecyclerView
, tek bir öğeyi güncellemek için zengin bir API'ye sahiptir. notifyItemChanged()
işlevini kullanarak RecyclerView
'a bir öğenin değiştiğini bildirebilirsiniz. Eklenen, kaldırılan veya taşınan öğeler için de benzer işlevler kullanabilirsiniz. Bu işlemleri manuel olarak da yapabilirsiniz ancak bu görev kolay olmayacak ve oldukça fazla kod içerebilir.
Neyse ki daha iyi bir yol var.
DiffUtil verimlidir ve zorlu işleri sizin için yapar.
RecyclerView
, iki liste arasındaki farkları hesaplamak için kullanılan DiffUtil
adlı bir sınıfa sahiptir. DiffUtil
, eski ve yeni listeyi alıp aradaki farkı bulur. Eklenen, kaldırılan veya değiştirilen öğeleri bulur. Daha sonra Eugene W. Myers'ın fark algoritması kullanılarak eski listeden yeni listeyi oluşturmak için yapılması gereken minimum değişiklik sayısı belirlenir.
DiffUtil
, neyin değiştiğini anladıktan sonra RecyclerView
bu bilgileri yalnızca değiştirilen, eklenen, kaldırılan veya taşınan öğeleri güncellemek için kullanabilir. Bu, listenin tamamını yeniden yapmaktan çok daha verimlidir.
Bu görevde, SleepNightAdapter
öğesini DiffUtil
kullanarak RecyclerView
öğesini verilerdeki değişikliklere göre optimize edecek şekilde yükseltiyorsunuz.
1. adım: SleepNightDiffCallback'i uygulayın
DiffUtil
sınıfının işlevlerini kullanmak için DiffUtil.ItemCallback
sınıfını genişletin.
SleepNightAdapter.kt
adlı kişiyi aç.SleepNightAdapter
için tam sınıf tanımının altında,DiffUtil.ItemCallback
'yi genişletenSleepNightDiffCallback
adlı yeni bir üst düzey sınıf oluşturun.SleepNight
öğesini genel bir parametre olarak iletin.
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}
- İmleci
SleepNightDiffCallback
sınıf adının içine yerleştirin. Alt+Enter
(Mac'teOption+Enter
) tuşuna basın ve Implement Members'ı (Üyeleri Uygula) seçin.- Açılan iletişim kutusunda,
areItemsTheSame()
veareContentsTheSame()
yöntemlerini seçmek için sol tıklarken Shift tuşunu basılı tutun, ardından Tamam'ı tıklayın.
Bu işlem, aşağıdaki örnekte gösterildiği gibi iki yöntem içinSleepNightDiffCallback
içinde 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.
}
areItemsTheSame()
içinde,TODO
yerine, iletilen ikiSleepNight
öğenin (oldItem
venewItem
) aynı olup olmadığını test eden kodu girin. ÖğelerinnightId
değeri aynıysa aynı öğe oldukları içintrue
değerini döndürün. Aksi takdirdefalse
değerini döndürür.DiffUtil
, bir öğenin eklenip eklenmediğini, kaldırılıp kaldırılmadığını veya taşınıp taşınmadığını belirlemek için bu testi kullanır.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem.nightId == newItem.nightId
}
areContentsTheSame()
içindeoldItem
venewItem
'nin aynı verileri içerip içermediğini, yani eşit olup olmadığını kontrol edin. Bu eşitlik kontrolü,SleepNight
bir veri sınıfı olduğundan tüm alanları kontrol eder.Data
sınıfları,equals
ve birkaç başka yöntemi sizin için otomatik olarak tanımlar.oldItem
venewItem
arasında farklılıklar varsa bu kod,DiffUtil
öğesinin güncellendiğini bildirir.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem == newItem
}
Değişen bir listeyi görüntülemek için RecyclerView
kullanmak yaygın bir yöntemdir. RecyclerView
, liste destekli bir RecyclerView
bağdaştırıcısı oluşturmanıza yardımcı olan bir bağdaştırıcı sınıfı (ListAdapter
) sağlar.
ListAdapter
, liste için izleme yapar 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
SleepNightAdapter.kt
dosyasında,SleepNightAdapter
sınıfının imzasınıListAdapter
'yi genişletecek şekilde değiştirin.- İstenirse
androidx.recyclerview.widget.ListAdapter
dosyasını içe aktarın. SleepNight
değerini,SleepNightAdapter.ViewHolder
değerinden önceListAdapter
işlevine ilk bağımsız değişken olarak ekleyin.SleepNightDiffCallback()
öğesini oluşturucuya parametre olarak ekleyin.ListAdapter
, listede neyin değiştiğini anlamak için bunu kullanır. TamamlanmışSleepNightAdapter
sınıf imzanız aşağıdaki gibi görünmelidir.
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
SleepNightAdapter
sınıfının içinde, ayarlayıcı da dahil olmak üzeredata
alanını silin.ListAdapter
, liste takibini sizin için yaptığından artık bu listeye ihtiyacınız yoktur.getItemCount()
geçersiz kılmasını silin. ÇünküListAdapter
bu yöntemi sizin için uygular.onBindViewHolder()
içindeki hatayı düzeltmek içinitem
değişkenini değiştirin.item
almak içindata
kullanmak yerineListAdapter
tarafından sağlanangetItem(position)
yöntemini çağırın.
val item = getItem(position)
2. adım: Listeyi güncel tutmak için submitList() işlevini kullanın
Kodunuz, değiştirilmiş bir liste olduğunda ListAdapter
'ya bilgi vermelidir. ListAdapter
, listenin yeni bir sürümünün kullanıma sunulduğunu ListAdapter
'ya bildirmek için submitList()
adlı bir yöntem sağlar. Bu yöntem çağrıldığında ListAdapter
, yeni listeyi eski listeyle karşılaştırır ve eklenen, kaldırılan, taşınan veya değiştirilen öğeleri algılar. Ardından ListAdapter
, RecyclerView
tarafından gösterilen öğeleri günceller.
SleepTrackerFragment.kt
adlı kişiyi aç.onCreateView()
içinde,sleepTrackerViewModel
üzerindeki gözlemcide, sildiğinizdata
değişkenine referans verilen hatayı bulun.adapter.data = it
yerineadapter.submitList(it)
ile görüşme isteği gönderin. Güncellenen kod aşağıda gösterilmektedir.
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.submitList(it)
}
})
- Uygulamanızı çalıştırın. Uygulamanız daha hızlı çalışır. Listeniz küçükse bu hız farkı fark edilmeyebilir.
Bu görevde, veri bağlamayı ayarlamak için önceki codelab'lerdekiyle aynı tekniği kullanacak ve findViewById()
çağrılarını ortadan kaldıracaksınız.
1. adım: Düzen dosyasına veri bağlama ekleyin
list_item_sleep_night.xml
düzen dosyasını Metin sekmesinde açın.- İmleci
ConstraintLayout
etiketinin üzerine getirin veAlt+Enter
tuşuna (Mac'teOption+Enter
) basın. Amaç menüsü ("hızlı düzeltme" menüsü) açılır. - Veri bağlama düzenine dönüştür'ü seçin. Bu işlem, düzeni
<layout>
içine sarar ve içine bir<data>
etiketi ekler. - Gerekirse en üste geri kaydırın ve
<data>
etiketi içindesleep
adlı bir değişken tanımlayın. type
,SleepNight
'nin tam nitelikli adı olmalıdır,com.example.android.trackmysleepquality.database.SleepNight
. Tamamlanmış<data>
etiketiniz aşağıdaki gibi görünmelidir.
<data>
<variable
name="sleep"
type="com.example.android.trackmysleepquality.database.SleepNight"/>
</data>
Binding
nesnesinin oluşturulmasını zorlamak için Build > Clean Project'i (Derle > Projeyi Temizle) ve ardından Build > Rebuild Project'i (Derle > Projeyi Yeniden Derle) seçin. (Hâlâ sorun yaşıyorsanız Dosya > Önbellekleri Geçersiz Kıl / Yeniden Başlat'ı seçin.) İlgili kodla birlikteListItemSleepNightBinding
bağlama nesnesi, projenin oluşturulan dosyalarına eklenir.
2. adım: Veri bağlama kullanarak öğe düzenini genişletin
SleepNightAdapter.kt
adlı kişiyi aç.ViewHolder
sınıfındafrom()
yöntemini bulun.view
değişkeninin bildirimini silin.
Silinecek kod:
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night, parent, false)
view
değişkeninin bulunduğu yerde, aşağıdaki örnekte gösterildiği gibiListItemSleepNightBinding
bağlama nesnesini genişletenbinding
adlı yeni bir değişken tanımlayın. Bağlama nesnesinin gerekli içe aktarma işlemini yapın.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)
- İşlevin sonunda
view
değerini döndürmek yerinebinding
değerini döndürün.
return ViewHolder(binding)
- Hatayı düzeltmek için imlecinizi
binding
kelimesinin üzerine getirin. Amacınıza uygun menüyü açmak içinAlt+Enter
(Mac'teOption+Enter
) tuşuna basın.
- Change parameter 'itemView' type of primary constructor of class 'ViewHolder' to 'ListItemSleepNightBinding' (Sınıfın birincil oluşturucusunun "itemView" parametre türünü "ListItemSleepNightBinding" olarak değiştir) seçeneğini belirleyin. Bu işlem,
ViewHolder
sınıfının parametre türünü günceller.
- İmzadaki değişikliği görmek için
ViewHolder
sınıf tanımına doğru yukarı kaydırın.itemView
yöntemindeitemView
değerinibinding
olarak değiştirdiğiniz içinitemView
ile ilgili bir hata görüyorsunuz.ViewHolder
sınıf tanımında,itemView
değerinin oluşumlarından birini sağ tıklayın ve Yeniden düzenle > Yeniden adlandır'ı seçin.from()
Adıbinding
olarak değiştirin. - Oluşturucu parametresinin
binding
başınaval
ekleyerek bunu bir özellik haline getirin. RecyclerView.ViewHolder
üst sınıfına yapılan çağrıda parametreyibinding
değerindenbinding.root
değerine değiştirin.View
değerini iletmeniz gerekir vebinding.root
, öğe düzeninizdeki kökConstraintLayout
'dir.- Tamamlanmış sınıf beyanınız aşağıdaki koda benzemelidir.
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){
Ayrıca findViewById()
çağrılarıyla ilgili bir hata görürsünüz ve bunu bir sonraki adımda düzeltirsiniz.
3. adım: findViewById() işlevini değiştirin
Artık sleepLength
, quality
ve qualityImage
özelliklerini findViewById()
yerine binding
nesnesini kullanacak şekilde güncelleyebilirsiniz.
sleepLength
,qualityString
vequalityImage
başlatmalarını, aşağıda gösterildiği gibibinding
nesnesinin görünümlerini kullanacak şekilde değiştirin. Bu işlemden sonra kodunuzda başka hata gösterilmemelidir.
val sleepLength: TextView = binding.sleepLength
val quality: TextView = binding.qualityString
val qualityImage: ImageView = binding.qualityImage
Bağlama nesnesi yerindeyken sleepLength
, quality
ve qualityImage
özelliklerini artık tanımlamanız gerekmez. DataBinding
aramaları önbelleğe alacağından bu özelliklerin bildirilmesine gerek yoktur.
sleepLength
,quality
vequalityImage
mülk adlarını sağ tıklayın. Refactor > Inline'ı seçin veyaControl+Command+N
tuşuna (Mac'teOption+Command+N
) basın.- Uygulamanızı çalıştırın. (Hata varsa projenizi Temizlemeniz ve Yeniden Oluşturmanız gerekebilir.)
Bu görevde, uygulamalarınızdaki verileri ayarlamak için bağlama bağdaştırıcılarıyla birlikte veri bağlamayı kullanacak şekilde uygulamanızı yükseltirsiniz.
Önceki bir codelab'de, LiveData
almak ve metin görünümlerinde görüntülenecek biçimlendirilmiş dizeler oluşturmak için Transformations
sınıfını kullanmıştı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 bağdaştırıcıları sağlayabilirsiniz. Adaptörleri bağlama, verilerinizi alıp bunları, veri bağlamanın bir görünümü bağlamak için kullanabileceği bir şeye (ör. metin veya resim) uyarlayan adaptörlerdir.
Üç bağlama bağdaştırıcısı uygulayacaksınız: biri kaliteli resim için, diğerleri ise her metin alanı için. Özetle, bağlama bağdaştırıcısı bildirmek için bir öğe ve görünüm alan bir yöntem tanımlar ve bunu @BindingAdapter
ile açıklama ekleyerek belirtirsiniz. Dönüşümü yöntemin gövdesinde uygularsınız. Kotlin'de, verileri alan görünüm sınıfında bir bağlama bağdaştırıcısı uzantı işlevi olarak yazabilirsiniz.
1. adım: Bağlama bağdaştırıcıları oluşturun
Bu adımda bir dizi sınıfı içe aktarmanız gerektiğini ve bunların tek tek belirtilmeyeceğini unutmayın.
SleepNightAdapater.kt
adlı kişiyi aç.ViewHolder
sınıfındabind()
yöntemini bulun ve bu yöntemin ne yaptığını hatırlayın.binding.sleepLength
,binding.quality
vebinding.qualityImage
değerlerini hesaplayan kodu alıp bunun yerine bağdaştırıcı içinde kullanacaksınız. (Şimdilik kodu olduğu gibi bırakın. Daha sonraki bir adımda taşıyacaksınız.)sleeptracker
paketindeBindingUtils.kt
adlı bir dosya oluşturup açın.TextView
üzerindesetSleepDurationFormatted
adlı bir uzantı işlevi tanımlayın veSleepNight
iletin. Bu işlev, uyku süresini hesaplama ve biçimlendirme konusunda adaptörünüz olacaktır.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}
setSleepDurationFormatted
gövdesinde, verileriViewHolder.bind()
bölümünde yaptığınız gibi görünüme bağlayın.convertDurationToFormatted()
işlevini çağırın ve ardındanTextView
öğesinintext
özelliğini biçimlendirilmiş metin olarak ayarlayın. (Bu,TextView
üzerindeki bir uzantı işlevi olduğundantext
mülküne doğrudan erişebilirsiniz.)
text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, context.resources)
- Bu bağlama bağdaştırıcısı hakkında veri bağlamaya bilgi vermek için işlevi
@BindingAdapter
ile açıklama ekleyin. - Bu işlev,
sleepDurationFormatted
özelliği için bağdaştırıcıdır. Bu nedenle,sleepDurationFormatted
değerini@BindingAdapter
işlevine bağımsız değişken olarak iletin.
@BindingAdapter("sleepDurationFormatted")
- İkinci bağdaştırıcı, uyku kalitesini
SleepNight
nesnesindeki değere göre ayarlar.TextView
üzerindesetSleepQualityString()
adlı bir uzantı işlevi oluşturun veSleepNight
değerini iletin. - Gövdede, verileri
ViewHolder.bind()
bölümünde yaptığınız gibi görünüme bağlayın.convertNumericQualityToString
'ı arayıptext
'ı ayarlayın. - İşlevi
@BindingAdapter("sleepQualityString")
ile açıklama ekleyin.
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight) {
text = convertNumericQualityToString(item.sleepQuality, context.resources)
}
- Üçüncü bağlama adaptörü, resmi bir resim görünümüne ayarlar.
ImageView
üzerinde uzantı işlevini oluşturun,setSleepImage
'ı çağırın veViewHolder.bind()
'daki kodu aşağıdaki şekilde 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
SleepNightAdapter.kt
adlı kişiyi aç.- Artık veri bağlama ve yeni bağdaştırıcılarınızı kullanarak bu işi sizin için yapabileceğinizden
bind()
yöntemindeki her şeyi silin.
fun bind(item: SleepNight) {
}
bind()
içinde, bağlama nesnesine yeniSleepNight
hakkında bilgi vermeniz gerektiğindenitem
için uyku durumunu atayın.
binding.sleep = item
- Bu satırın altına
binding.executePendingBindings()
ekleyin. Bu çağrı, veri bağlamadan bekleyen bağlamaları hemen yürütmesini isteyen bir optimizasyondur. Görünümlerin boyutlandırılmasını biraz hızlandırabileceğinden, bağlama bağdaştırıcılarınıRecyclerView
içinde kullanırken her zamanexecutePendingBindings()
işlevini çağırmak iyi bir fikirdir.
binding.executePendingBindings()
3. adım: XML düzenine bağlamalar ekleyin
list_item_sleep_night.xml
adlı kişiyi aç.ImageView
içinde, resmi ayarlayan bağlama bağdaştırıcısıyla aynı ada sahip birapp
özelliği ekleyin. Aşağıda gösterildiği gibisleep
değişkenini iletin.
Bu özellik, bağdaştırıcı aracılığıyla görünüm ile bağlama nesnesi arasında bağlantı oluşturur.sleepImage
her referans verildiğinde bağdaştırıcı,SleepNight
verilerini uyarlar.
app:sleepImage="@{sleep}"
- Aynı işlemi
sleep_length
vequality_string
metin görünümleri için de yapın.sleepDurationFormatted
veyasleepQualityString
her referans verildiğinde bağdaştırıcılar,SleepNight
'deki verileri uyarlar.
app:sleepDurationFormatted="@{sleep}"
app:sleepQualityString="@{sleep}"
- Uygulamanızı çalıştırın. Uygulamanız, eskiden olduğu gibi çalışır. Bağlama bağdaştırıcıları, veriler değiştikçe görünümleri biçimlendirme ve güncelleme işinin tamamını halleder. Böylece
ViewHolder
basitleşir ve kod, eskisinden çok daha iyi bir yapıya sahip olur.
Son birkaç egzersiz için aynı listeyi görüntülediniz. Bu, Adapter
arayüzünün kodunuzu birçok farklı şekilde yapılandırmanıza olanak tanıdığını göstermek için tasarlanmıştır. Kodunuz ne kadar karmaşıksa iyi bir mimari oluşturmak o kadar önemli hale gelir. Üretim uygulamalarında bu kalıplar ve diğerleri RecyclerView
ile birlikte kullanılır. Tüm desenler çalışır ve her birinin avantajları vardır. Hangisini seçeceğiniz, ne oluşturduğunuza bağlıdır.
Tebrikler! Bu noktada, Android'de RecyclerView
'da uzmanlaşma yolunda önemli bir adım atmış olursunuz.
Android Studio projesi: RecyclerViewDiffUtilDataBinding.
DiffUtil
:
RecyclerView
, iki liste arasındaki farkları hesaplamak için kullanılanDiffUtil
adlı bir sınıfa sahiptir.DiffUtil
, iki liste arasındaki farkı bulmak için genişlettiğinizItemCallBack
adlı bir sınıfa sahiptir.ItemCallback
sınıfında,areItemsTheSame()
veareContentsTheSame()
yöntemlerini geçersiz kılmanız gerekir.
ListAdapter
:
- Ücretsiz olarak liste yönetimi yapmak için
RecyclerView.Adapter
yerineListAdapter
sınıfını kullanabilirsiniz. AncakListAdapter
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 nasıl yapılacağı gösterilmektedir. - Android Studio'da niyet menüsünü açmak için imleci herhangi bir kod öğesinin üzerine getirin ve
Alt+Enter
(Mac'teOption+Enter
) tuşuna basın. Bu menü, özellikle kodu yeniden düzenlemek ve yöntemleri uygulamak için saplar oluşturmak açısından 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ğlamayı kullanın.
Bağlama adaptörleri:
- Daha önce verilerden dizeler oluşturmak için
Transformations
kullandınız. Farklı veya karmaşık türlerdeki verileri bağlamanız gerekiyorsa veri bağlamanın bunları kullanmasına yardımcı olmak için bağlama bağdaştırıcıları sağlayın. - Bağlama bağdaştırıcısı bildirmek için bir öğe ve görünüm alan bir yöntem tanımlayın ve yöntemi
@BindingAdapter
ile ek açıklama olarak belirtin. Kotlin'de bağlama bağdaştırıcısınıView
üzerinde bir uzantı işlevi olarak yazabilirsiniz. Adaptörün uyarladığı özelliğin adını iletin. Örneğin:
@BindingAdapter("sleepDurationFormatted")
- XML düzeninde, bağlama bağdaştırıcısıyla aynı ada sahip bir
app
özelliği ayarlayın. Verilerle birlikte bir değişken iletin. Örneğin:
.app:sleepDurationFormatted="@{sleep}"
Udacity kursları:
Android geliştirici belgeleri:
- RecyclerView ile liste oluşturma
RecyclerView
DiffUtil
- Veri Bağlama Kitaplığı
- Bağlama adaptörleri
notifyDataSetChanged()
Transformations
Diğer kaynaklar:
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
DiffUtil
kullanmak için aşağıdakilerden hangileri gereklidir? Uygun olan tüm seçenekleri işaretleyin.
▢ ItemCallBack
dersini uzatın.
▢ Geçersiz kıl areItemsTheSame()
.
▢ Geçersiz kıl areContentsTheSame()
.
▢ Öğeler arasındaki farkları izlemek için veri bağlamayı kullanın.
Soru 2
Aşağıdakilerden hangisi bağlama bağdaştırıcıları hakkında doğrudur?
▢ Bağlama bağdaştırıcısı, @BindingAdapter
ile açıklama eklenmiş bir işlevdir.
▢ Bağlama bağdaştırıcısı kullanarak veri biçimlendirmeyi görünüm tutucudan ayırabilirsiniz.
▢ Bağlama adaptörlerini kullanmak istiyorsanız RecyclerViewAdapter
kullanmanız gerekir.
▢ Bağlama bağdaştırıcıları, karmaşık verileri dönüştürmeniz gerektiğinde iyi bir çözümdür.
3. Soru
Ne zaman bağlama adaptörü yerine Transformations
kullanmayı düşünmelisiniz? Uygun olan tüm seçenekleri işaretleyin.
▢ Verileriniz basit olmalıdır.
▢ Bir dizeyi biçimlendiriyorsunuz.
▢ Listeniz çok uzun.
▢ ViewHolder
yalnızca bir görünüm içeriyor.
Bir sonraki derse başlayın: