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 codelab'de, öğe listelerini görüntülemek için RecyclerView nasıl kullanılacağı açıklanmaktadır. Önceki codelab serisindeki uyku takipçisi uygulamasını temel alarak, önerilen mimariye sahip bir RecyclerView kullanarak verileri görüntülemenin daha iyi ve daha çok yönlü bir yolunu öğrenirsiniz.
Bilmeniz gerekenler
Aşağıdaki konular hakkında bilgi sahibi olmanız gerekir:
- Etkinlik, parçalar ve görünümler kullanarak temel bir kullanıcı arayüzü (UI) oluşturma.
- Parçalar arasında gezinme ve parçalar arasında veri aktarmak için
safeArgskullanma. - Görünüm modelleri, görünüm modeli fabrikaları, dönüşümler ve
LiveDataile gözlemcilerini kullanma. Roomveritabanı oluşturma, DAO oluşturma ve varlıkları tanımlama- Veritabanı görevleri ve uzun süren diğer görevler için eş yordamları kullanma.
Neler öğreneceksiniz?
- Öğe listesini görüntülemek için
RecyclerViewileAdapterveViewHoldernasıl kullanılır?
Yapacaklarınız
- Önceki dersteki TrackMySleepQuality uygulamasını, uyku kalitesi verilerini görüntülemek için
RecyclerViewkullanacak şekilde değiştirin.
Bu codelab'de, uyku kalitesini takip eden bir uygulamanın RecyclerView bölümünü oluşturacaksınız. Uygulama, uyku verilerini zaman içinde saklamak için Room veritabanını kullanır.
Başlangıç seviyesindeki uyku takipçisi uygulamasında, aşağıdaki şekilde gösterildiği gibi parçalarla temsil edilen iki ekran bulunur.

Solda gösterilen ilk ekranda izlemeyi başlatma ve durdurma düğmeleri bulunur. Bu ekranda kullanıcının tüm uyku verileri de 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, kullanıcı arayüzü denetleyicisi, ViewModel ve LiveData ile basitleştirilmiş bir mimari kullanır. Uygulama, uyku verilerini kalıcı hale getirmek için Room veritabanını da kullanır.

İlk ekranda gösterilen uyku geceleri listesi işlevseldir ancak çok güzel görünmez. Uygulama, metin görünümü için metin dizeleri ve kalite için sayılar oluşturmak üzere karmaşık bir biçimlendirici kullanır. Ayrıca bu tasarım ölçeklenemez. Bu codelab'deki tüm sorunları düzelttikten sonra nihai uygulama aynı işlevselliğe sahip olur ve ana ekran aşağıdaki gibi görünür:

Android'de en sık kullanılan kullanıcı arayüzü görevlerinden biri, veri listesi veya ızgarası görüntülemektir. Listeler basit olabileceği gibi çok karmaşık da olabilir. Metin görünümleri listesinde alışveriş listesi gibi basit veriler gösterilebilir. Tatil yerlerinin açıklamalı listesi gibi karmaşık bir listede, kullanıcıya başlıklar içeren kaydırılabilir bir ızgarada birçok ayrıntı gösterilebilir.
Android, tüm bu kullanım alanlarını desteklemek için RecyclerView widget'ını sunar.

RecyclerView'nın en büyük avantajı, büyük listeler için çok verimli olmasıdır:
- Varsayılan olarak
RecyclerViewyalnızca ekranda görünür durumda olan öğeleri işlemek veya çizmek için çalışır. Örneğin, listenizde bin öğe varsa ancak yalnızca 10 öğe görünür durumdaysaRecyclerView, ekranda 10 öğe çizmek için yeterli miktarda işlem yapar. Kullanıcı kaydırdığındaRecyclerView, ekranda hangi yeni öğelerin olması gerektiğini belirler ve bu öğeleri görüntülemek için gereken kadar işlem yapar. - Ekranın dışına kaydırılan öğelerin görünümleri geri dönüştürülür. Bu durumda, öğe ekrana kaydırılan yeni içerikle doldurulur. Bu
RecyclerViewdavranış, işlem süresini önemli ölçüde kısaltır ve listelerin akıcı bir şekilde kaydırılmasına yardımcı olur. - Bir öğe değiştiğinde
RecyclerView, listenin tamamını yeniden çizmek yerine yalnızca o öğeyi güncelleyebilir. Bu, karmaşık öğelerin listelerini görüntülerken büyük bir verimlilik artışı sağlar.
Aşağıdaki sırayı incelediğinizde bir görünümün verilerle doldurulduğunu görebilirsiniz ABC. Bu görünüm ekrandan çıktıktan sonra RecyclerView, görünümü yeni veriler için yeniden kullanır XYZ.
Adaptör deseni
Farklı elektrik prizlerinin kullanıldığı ülkeler arasında seyahat ediyorsanız cihazlarınızı adaptör kullanarak prizlere nasıl takabileceğinizi biliyorsunuzdur. Adaptör, bir tür fişi başka bir türe dönüştürmenizi sağlar. Bu da aslında bir arayüzü başka bir arayüze dönüştürmek anlamına gelir.
Yazılım mühendisliğinde adaptör deseni, bir nesnenin başka bir API ile çalışmasına yardımcı olur. RecyclerView, uygulama verilerini RecyclerView'nın gösterebileceği bir şeye dönüştürmek için bir bağdaştırıcı kullanır. Bu işlem sırasında uygulamanın verileri depolama ve işleme şekli değiştirilmez. Uyku izleme uygulaması için, Room veritabanındaki verileri ViewModel'ı değiştirmeden RecyclerView'ın nasıl göstereceğini bildiği bir şeye uyarlayan bir bağdaştırıcı oluşturursunuz.
RecyclerView'ı uygulama

Verilerinizi RecyclerView içinde göstermek için aşağıdaki bölümlere ihtiyacınız vardır:
- Görüntülenecek veriler.
- Görünümler için kapsayıcı görevi görecek şekilde düzen dosyanızda tanımlanmış bir
RecyclerViewörneği. - Bir veri öğesinin düzeni.
Tüm liste öğeleri aynı görünüyorsa hepsi için aynı düzeni kullanabilirsiniz ancak bu zorunlu değildir. Öğe düzeni, parçanın düzeninden ayrı olarak oluşturulmalıdır. Böylece, tek seferde bir öğe görünümü oluşturulabilir ve verilerle doldurulabilir. - Düzen yöneticisi.
Düzen yöneticisi, bir görünümdeki kullanıcı arayüzü bileşenlerinin düzenini yönetir. - Görünüm tutucu.
Görünüm tutucu,ViewHoldersınıfını genişletir. Öğenin düzeninden bir öğeyi görüntülemek için görünüm bilgilerini içerir. Görünüm tutucular, görünümleri ekranda verimli bir şekilde taşımak için kullanılan bilgileri de ekler.RecyclerView - Bir bağdaştırıcı.
Bağdaştırıcı, verileriniziRecyclerView'ye bağlar. VerileriViewHolderiçinde görüntülenebilecek şekilde uyarlar. BirRecyclerView, verilerin ekranda nasıl görüntüleneceğini belirlemek için bağdaştırıcıyı kullanır.
Bu görevde, düzen dosyanıza RecyclerView ekleyip uyku verilerini RecyclerView'ya göstermek için Adapter ayarlayacaksınız.
1. adım: LayoutManager ile RecyclerView ekleyin
Bu adımda, fragment_sleep_tracker.xml dosyasında ScrollView yerine RecyclerView yazacaksınız.
- GitHub'dan RecyclerViewFundamentals-Starter uygulamasını indirin.
- Uygulamayı oluşturup çalıştırın. Verilerin nasıl basit metin olarak gösterildiğine dikkat edin.
- Android Studio'daki Tasarım sekmesinde
fragment_sleep_tracker.xmldüzen dosyasını açın. - Bileşen Ağacı bölmesinde
ScrollViewöğesini silin. Bu işlem,ScrollViewiçindekiTextViewöğesini de siler. - Palet bölmesinde, soldaki bileşen türleri listesinde Kapsayıcılar'ı bulup seçin.
RecyclerViewsimgesini Palet bölmesinden Bileşen Ağacı bölmesine sürükleyin.RecyclerViewcihazınıConstraintLayoutiçine yerleştirin.

- Bağımlılık eklemek isteyip istemediğinizi soran bir iletişim kutusu açılırsa Android Studio'nun
recyclerviewbağımlılığını Gradle dosyanıza eklemesine izin vermek için Tamam'ı tıklayın. Bu işlem birkaç saniye sürebilir. Ardından uygulamanız senkronize edilir.

- Modül
build.gradledosyasını açın, sonuna gidin ve aşağıdaki koda benzeyen yeni bağımlı öğeyi not edin:
implementation 'androidx.recyclerview:recyclerview:1.0.0'
fragment_sleep_tracker.xml'a geri dönün.- Metin sekmesinde, aşağıda gösterilen
RecyclerViewkodunu bulun:
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent" />RecyclerViewiçinidsleep_listverin.
android:id="@+id/sleep_list"RecyclerViewsimgesini,ConstraintLayoutsimgesinin içindeki ekranın kalan kısmını kaplayacak şekilde konumlandırın. Bunu yapmak içinRecyclerViewsimgesinin üst kısmını Başlat düğmesiyle, alt kısmını Temizle düğmesiyle ve her iki tarafını da üst öğeyle sınırlayın. Düzen Düzenleyici'de veya XML'de aşağıdaki kodu kullanarak düzen genişliğini ve yüksekliğini 0 dp olarak ayarlayın:
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/clear_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stop_button"RecyclerViewXML'sine bir düzen yöneticisi ekleyin. HerRecyclerView, listedeki öğelerin nasıl konumlandırılacağını belirten bir düzen yöneticisine ihtiyaç duyar. Android, öğeleri varsayılan olarak tam genişlikteki satırlardan oluşan dikey bir listede düzenleyen birLinearLayoutManagersağlar.
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"- Tasarım sekmesine geçin ve eklenen kısıtlamaların
RecyclerViewsimgesinin kullanılabilir alanı dolduracak şekilde genişlemesine neden olduğunu fark edin.

2. adım: Liste öğesi düzenini ve metin görünümü tutucusunu oluşturun
RecyclerView yalnızca bir kapsayıcıdır. Bu adımda, RecyclerView içinde gösterilecek öğelerin düzenini ve altyapısını oluşturursunuz.
Çalışan bir RecyclerView'ya olabildiğince hızlı ulaşmak için başlangıçta yalnızca uyku kalitesini sayı olarak gösteren basit bir liste öğesi kullanırsınız. Bunun için bir görünüm tutucuya (TextItemViewHolder) ihtiyacınız vardır. Veriler için bir görünüm (TextView) de gerekir. (Daha sonraki bir adımda, görünüm tutucular ve tüm uyku verilerini nasıl düzenleyeceğiniz hakkında daha fazla bilgi edineceksiniz.)
text_item_view.xmladlı bir düzen dosyası oluşturun. Şablon kodunu değiştireceğiniz için kök öğe olarak ne kullandığınız önemli değildir.text_item_view.xmlbölümünde, verilen tüm kodu silin.- Başında ve sonunda
16dpdolgusu olan birTextViewekleyin ve metin boyutunu24spolarak ayarlayın. Genişlik üst öğeyle eşleşsin, yükseklik ise içeriği sarsın. Bu görünümRecyclerViewiçinde gösterildiğinden görünümüViewGroupiçine yerleştirmeniz gerekmez.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:textSize="24sp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />Util.ktadlı kişiyi aç. En sona gidin veTextItemViewHoldersınıfını oluşturan aşağıdaki tanımı ekleyin. Kodu, dosyanın en altına, son kapanış ayracından sonra yerleştirin. Bu görünüm tutucu geçici olduğundan ve daha sonra değiştireceğiniz için kodUtil.ktiçine yerleştirilir.
class TextItemViewHolder(val textView: TextView): RecyclerView.ViewHolder(textView)- İstenirse
android.widget.TextViewveandroidx.recyclerview.widget.RecyclerViewdosyalarını içe aktarın.
3. adım: SleepNightAdapter oluşturun
RecyclerView uygulamasındaki temel görev, bağdaştırıcıyı oluşturmaktır. Öğe görünümü için basit bir görünüm tutucunuz ve her öğe için bir düzeniniz vardır. Artık bağdaştırıcı oluşturabilirsiniz. Adaptör, bir görünüm tutucu oluşturur ve RecyclerView için görüntülenecek verilerle doldurur.
sleeptrackerpaketindeSleepNightAdapteradlı yeni bir Kotlin sınıfı oluşturun.SleepNightAdaptersınıfınıRecyclerView.Adaptersınıfını genişletecek şekilde oluşturun. Bu sınıfaSleepNightAdapteradı verilir. ÇünküSleepNightnesnesiniRecyclerViewtarafından kullanılabilecek bir şeye dönüştürür. Bağdaştırıcının hangi görünüm tutucusunu kullanacağını bilmesi gerekir. Bu nedenle,TextItemViewHolderdeğerini iletin. İstendiğinde gerekli bileşenleri içe aktarın. Ardından, uygulanması zorunlu yöntemler olduğundan bir hata görürsünüz.
class SleepNightAdapter: RecyclerView.Adapter<TextItemViewHolder>() {}SleepNightAdapter'nın en üst düzeyinde, verileri tutmak için birlistOfSleepNightdeğişkeni oluşturun.
var data = listOf<SleepNight>()SleepNightAdapteriçinde,data'deki uyku geceleri listesinin boyutunu döndürmek içingetItemCount()değerini geçersiz kılın.RecyclerView, görüntüleyeceği öğe sayısını bilmelidir. Bunu dagetItemCount()işlevini çağırarak yapar.
override fun getItemCount() = data.sizeSleepNightAdapteriçinde, aşağıda gösterildiği gibionBindViewHolder()işlevini geçersiz kılın.onBindViewHolder()işlevi, belirtilen konumdaki bir liste öğesinin verilerini görüntülemek içinRecyclerViewtarafından çağrılır. Bu nedenleonBindViewHolder()yöntemi iki bağımsız değişken alır: görünüm tutucu ve bağlanacak verilerin konumu. Bu uygulamada, kart sahibiTextItemViewHolder, konum ise listedeki konumdur.
override fun onBindViewHolder(holder: TextItemViewHolder, position: Int) {
}onBindViewHolder()içinde, verilerde belirli bir konumdaki bir öğe için değişken oluşturun.
val item = data[position]- Oluşturduğunuz
ViewHolder,textViewadlı bir mülke sahip.onBindViewHolder()içinde,textViewöğesinintextdeğerini uyku kalitesi numarasına ayarlayın. Bu kod yalnızca bir sayı listesi gösterir ancak bu basit örnek, bağdaştırıcının verileri nasıl görünüm tutucuya ve ekrana getirdiğini görmenizi sağlar.
holder.textView.text = item.sleepQuality.toString()SleepNightAdapteriçinde,RecyclerViewbir öğeyi temsil etmek için görünüm tutucuya ihtiyaç duyduğunda çağrılanonCreateViewHolder()işlevini geçersiz kılın ve uygulayın.
Bu işlev iki parametre alır veViewHolderdöndürür. Görünüm tutucuyu barındıran görünüm grubu olanparentparametresi her zamanRecyclerViewolur.viewTypeparametresi, aynıRecyclerViewiçinde birden fazla görünüm olduğunda kullanılır. Örneğin, bir metin görünümü listesini, bir resmi ve bir videoyu aynıRecyclerViewiçine yerleştirirsenizonCreateViewHolder()işlevinin hangi tür görünümü kullanacağını bilmesi gerekir.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TextItemViewHolder {
}onCreateViewHolder()içindeLayoutInflaterörneği oluşturun.
Düzen genişletici, XML düzenlerinden nasıl görünüm oluşturulacağını bilir.context, görüntülemeyi doğru şekilde artırma hakkında bilgiler içerir. Bir geri dönüşüm görünümü için bağdaştırıcıda, her zamanparentgörünüm grubunun bağlamını (RecyclerView) iletirsiniz.
val layoutInflater = LayoutInflater.from(parent.context)onCreateViewHolder()içinde,layoutinflater'danviewşişirmesini isteyerekviewoluşturun.
Görünüm için XML düzenini ve görünüm içinparentgörünüm grubunu iletin. Üçüncü bağımsız değişken olan boole bağımsız değişkeniattachToRoot'dır. Bu bağımsız değişkenfalseolmalıdır. ÇünküRecyclerView, zamanı geldiğinde bu öğeyi görünüm hiyerarşisine sizin için ekler.
val view = layoutInflater
.inflate(R.layout.text_item_view, parent, false) as TextViewonCreateViewHolder()içindeviewile oluşturulanTextItemViewHolderdeğerini döndürün.
return TextItemViewHolder(view)RecyclerView, veriler hakkında hiçbir şey bilmediğindendatadeğiştiğinde bağdaştırıcınınRecyclerView'yı bilgilendirmesi gerekir. Yalnızca bağdaştırıcının kendisine verdiği görünüm tutucular hakkında bilgi sahibidir.
Görüntülediği veriler değiştiğindeRecyclerViewöğesine bilgi vermek içinSleepNightAdaptersınıfının en üstündekidatadeğişkenine özel bir ayarlayıcı ekleyin. Ayarlayıcıdadataiçin yeni bir değer verin, ardındannotifyDataSetChanged()işlevini çağırarak listenin yeni verilerle yeniden çizilmesini tetikleyin.
var data = listOf<SleepNight>()
set(value) {
field = value
notifyDataSetChanged()
}4. adım: RecyclerView'a Adapter hakkında bilgi verin
RecyclerView, görünüm tutucuları almak için kullanılacak bağdaştırıcı hakkında bilgi sahibi olmalıdır.
SleepTrackerFragment.ktadlı kişiyi aç.onCreateview()içinde bir bağdaştırıcı oluşturun. Bu kodu,ViewModelmodeli oluşturulduktan sonra vereturnifadesinden önce yerleştirin.
val adapter = SleepNightAdapter()adapterileRecyclerView'yi ilişkilendirin.
binding.sleepList.adapter = adapterbindingnesnesini güncellemek için projenizi temizleyip yeniden oluşturun.binding.sleepListveyabinding.FragmentSleepTrackerBindingile ilgili hataları görmeye devam ederseniz önbellekleri geçersiz kılın ve yeniden başlatın. (Dosya > Geçersiz Kılınan Önbellekler / Yeniden Başlat'ı seçin.)
Uygulamayı şimdi çalıştırırsanız hata olmaz ancak Başlat'a, ardından Durdur'a dokunduğunuzda herhangi bir veri gösterilmez.
5. adım: Adaptöre veri aktarın
Şu ana kadar bir adaptörünüz ve adaptörden RecyclerView'ya veri aktarmanın bir yolu var. Şimdi ViewModel'dan bağdaştırıcıya veri aktarmanız gerekiyor.
SleepTrackerViewModeladlı kişiyi aç.- Gösterilecek veriler olan tüm uyku gecelerini depolayan
nightsdeğişkenini bulun.nightsdeğişkeni, veritabanındagetAllNights()çağrılarak ayarlanır. - Bu değişkene erişmesi gereken bir gözlemci oluşturacağınız için
privatedeğişkenininightsöğesinden kaldırın. Beyanınız aşağıdaki gibi görünmelidir:
val nights = database.getAllNights()databasepaketindeSleepDatabaseDaodosyasını açın.getAllNights()işlevini bulun. Bu işlevin,SleepNightdeğerlerinin listesiniLiveDataolarak döndürdüğünü unutmayın. Bu,nightsdeğişkenininRoomtarafından güncel tutulanLiveDataiçerdiği ve ne zaman değiştiğini öğrenmek içinnightsdeğişkenini gözlemleyebileceğiniz anlamına gelir.SleepTrackerFragmentadlı kişiyi aç.onCreateView()içinde,adapteroluşturulduktan sonranightsdeğişkeninde bir gözlemci oluşturun. ParçanınviewLifecycleOwneröğesini yaşam döngüsü sahibi olarak sağlayarak bu gözlemcinin yalnızcaRecyclerViewekrandayken etkin olmasını sağlayabilirsiniz.
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
})- Gözlemcinin içinde, boş olmayan bir değer (
nightsiçin) aldığınızda değeri bağdaştırıcınındataöğesine atayın. Bu, gözlemci için tamamlanmış kod ve verilerin ayarlanmasıdır:
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.data = it
}
})- Kodunuzu oluşturup çalıştırın.
Adaptörünüz çalışıyorsa uyku kalitesiyle ilgili sayıları liste olarak görürsünüz. Soldaki ekran görüntüsünde, Başlat'a dokunduktan sonra -1 gösteriliyor. Sağdaki ekran görüntüsünde, Durdur'a dokunup kalite derecesi seçtikten sonra güncellenen uyku kalitesi sayısı gösterilmektedir.

6. adım: Görüntüleme kartlarının nasıl geri dönüştürüldüğünü inceleyin
RecyclerView Görünüm tutucuları geri dönüştürür. Bu, görünüm tutucuların yeniden kullanıldığı anlamına gelir. Bir görünüm ekranın dışına kaydırıldığında RecyclerView, ekranın içine kaydırılacak görünüm için görünümü yeniden kullanır.
Bu görünüm tutucular geri dönüştürüldüğünden onBindViewHolder(), önceki öğelerin görünüm tutucuda ayarlamış olabileceği tüm özelleştirmeleri ayarlar veya sıfırlar.
Örneğin, 1'e eşit veya 1'den küçük kalite derecelendirmelerini içeren ve kötü uyku kalitesini temsil eden görünüm tutucularda metin rengini kırmızı olarak ayarlayabilirsiniz.
SleepNightAdaptersınıfında,onBindViewHolder()öğesinin sonuna aşağıdaki kodu ekleyin.
if (item.sleepQuality <= 1) {
holder.textView.setTextColor(Color.RED) // red
}- Uygulamayı çalıştırın.
- Uyku kalitesi düşük veriler eklediğinizde sayı kırmızı olur.
- Ekranda kırmızı renkte yüksek bir sayı görene kadar uyku kalitesi için yüksek puanlar ekleyin.
RecyclerView, görünüm tutucuları yeniden kullandığı için sonunda yüksek kaliteli bir puan için kırmızı görünüm tutuculardan birini yeniden kullanır. Yüksek puan yanlışlıkla kırmızı renkte gösteriliyor.

- Bu sorunu düzeltmek için kalite değeri birden küçük veya bire eşit değilse rengi siyah olarak ayarlayan bir
elseifadesi ekleyin.
Her iki koşul da açıkça belirtildiğinde görünüm tutucu, her öğe için doğru metin rengini kullanır.
if (item.sleepQuality <= 1) {
holder.textView.setTextColor(Color.RED) // red
} else {
// reset
holder.textView.setTextColor(Color.BLACK) // black
}- Uygulamayı çalıştırın. Sayılar her zaman doğru renkte olmalıdır.
Tebrikler! Artık tamamen işlevsel bir temel RecyclerView hesabınız var.
Bu görevde, basit görünüm tutucuyu bir uyku gecesiyle ilgili daha fazla veri gösterebilen bir tutucuyla değiştireceksiniz.
Util.kt öğesine eklediğiniz basit ViewHolder, yalnızca TextView öğesini TextItemViewHolder içine sarar.
class TextItemViewHolder(val textView: TextView): RecyclerView.ViewHolder(textView)Peki neden RecyclerView doğrudan TextView kullanmıyor? Bu tek kod satırı birçok işlev sunar. ViewHolder, bir öğe görünümünü ve RecyclerView içindeki yeriyle ilgili meta verileri açıklar. RecyclerView, görünümü liste kaydırılırken doğru şekilde konumlandırmak ve Adapter'ye öğe eklenip kaldırıldığında görünümlere animasyon eklemek gibi ilgi çekici işlemler yapmak için bu işlevden yararlanır.
RecyclerView, ViewHolder içinde depolanan görünümlere erişmesi gerekiyorsa görünüm tutucunun itemView özelliğini kullanarak bunu yapabilir. RecyclerView, ekranda gösterilecek bir öğeyi bağlarken, bir görünümün etrafına kenarlık gibi süslemeler çizerken ve erişilebilirliği uygularken itemView kullanır.
1. adım: Öğenin düzenini oluşturun
Bu adımda bir öğe için düzen dosyasını oluşturursunuz. Düzende, uyku kalitesi için ConstraintLayout, uyku süresi için ImageView ve kalite için TextView simgesi ile kaliteyi metin olarak gösteren bir TextView yer alır. Daha önce düzen oluşturduğunuz için sağlanan XML kodunu kopyalayıp yapıştırın.
- Yeni bir düzen kaynak dosyası oluşturun ve dosyayı
list_item_sleep_nightolarak adlandırın. - Dosyadaki tüm kodu aşağıdaki kodla değiştirin. Ardından, yeni oluşturduğunuz düzeni inceleyin.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/quality_image"
android:layout_width="@dimen/icon_size"
android:layout_height="60dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@drawable/ic_sleep_5" />
<TextView
android:id="@+id/sleep_length"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/quality_image"
app:layout_constraintTop_toTopOf="@+id/quality_image"
tools:text="Wednesday" />
<TextView
android:id="@+id/quality_string"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="@+id/sleep_length"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/sleep_length"
app:layout_constraintTop_toBottomOf="@+id/sleep_length"
tools:text="Excellent!!!" />
</androidx.constraintlayout.widget.ConstraintLayout>- Android Studio'da Tasarım sekmesine geçin. Tasarım görünümünde düzeniniz aşağıdaki soldaki ekran görüntüsüne benzer. Plan görünümünde, sağdaki ekran görüntüsüne benzer.

2. adım: ViewHolder oluşturun
SleepNightAdapter.ktadlı kişiyi aç.SleepNightAdapteriçindeViewHolderadlı bir sınıf oluşturun ve bu sınıfıRecyclerView.ViewHolderolarak genişletin.
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){}ViewHolderiçinde görünümlere referanslar alın. BuViewHolderöğesinin güncelleyeceği görünümlere referans vermeniz gerekir. BuViewHolderöğesini her bağladığınızda resme ve her iki metin görünümüne erişmeniz gerekir. (Bu kodu daha sonra veri bağlama kullanacak şekilde dönüştüreceksiniz.)
val sleepLength: TextView = itemView.findViewById(R.id.sleep_length)
val quality: TextView = itemView.findViewById(R.id.quality_string)
val qualityImage: ImageView = itemView.findViewById(R.id.quality_image)3. adım: ViewHolder'ı SleepNightAdapter'da kullanın
SleepNightAdaptertanımındaTextItemViewHolderyerine yeni oluşturduğunuzSleepNightAdapter.ViewHolderöğesini kullanın.
class SleepNightAdapter: RecyclerView.Adapter<SleepNightAdapter.ViewHolder>() {onCreateViewHolder() adresini güncelleyin:
ViewHolderdeğerini döndürmek içinonCreateViewHolder()işlevinin imzasını değiştirin.- Düzen genişleticiyi doğru düzen kaynağını (
list_item_sleep_night) kullanacak şekilde değiştirin. TextViewcihazına yayınlama işlemini kaldırın.TextItemViewHolderyerineViewHolderdöndürün.
GüncellenmişonCreateViewHolder()işlevi tamamlandı:
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int): ViewHolder {
val layoutInflater =
LayoutInflater.from(parent.context)
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night,
parent, false)
return ViewHolder(view)
}onBindViewHolder() adresini güncelleyin:
onBindViewHolder()işlevinin imzasını,holderparametresiTextItemViewHolderyerineViewHolderolacak şekilde değiştirin.onBindViewHolder()içinde,itemtanımı hariç tüm kodu silin.- Bu görünüm için
resourcesöğesine referans içeren birvalrestanımlayın.
val res = holder.itemView.context.resourcessleepLengthmetin görünümünün metnini süre olarak ayarlayın. Başlangıç koduyla birlikte sağlanan bir biçimlendirme işlevini çağıran aşağıdaki kodu kopyalayın.
holder.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)- Bu işlem,
convertDurationToFormatted()tanımlanması gerektiğinden hata verir.Util.ktbağlantısını açın ve kodun yorumunu kaldırıp ilişkili içe aktarmaları yapın. (Kod > Satır yorumlarıyla yorum yap'ı seçin.) onBindViewHolder()'ya geri dönün ve kaliteyi ayarlamak içinconvertNumericQualityToString()'ı kullanın.
holder.quality.text= convertNumericQualityToString(item.sleepQuality, res)- Bu işlevleri manuel olarak içe aktarmanız gerekebilir.
import com.example.android.trackmysleepquality.convertDurationToFormatted
import com.example.android.trackmysleepquality.convertNumericQualityToString- Kalite için doğru simgeyi ayarlayın. Başlangıç kodunda yeni
ic_sleep_activesimgesi sağlanır.
holder.qualityImage.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
})onBindViewHolder()işlevinin güncellenmiş ve tamamlanmış halini aşağıda bulabilirsiniz. Bu işlev,ViewHolderiçin tüm verileri ayarlar:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = data[position]
val res = holder.itemView.context.resources
holder.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)
holder.quality.text= convertNumericQualityToString(item.sleepQuality, res)
holder.qualityImage.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
})
}- Uygulamanızı çalıştırın. Ekranınız aşağıdaki ekran görüntüsüne benzemeli, uyku süresi ve uyku kalitesiyle ilgili metinlerin yanı sıra uyku kalitesi simgesini göstermelidir.

RecyclerView tamamlandı. Adapter ve ViewHolder bileşenlerini nasıl uygulayacağınızı öğrendiniz ve bunları bir araya getirerek RecyclerView Adapter içeren bir liste görüntülediniz.
Şu ana kadar yazdığınız kodda, bağdaştırıcı ve görünüm tutucu oluşturma süreci gösteriliyor. Ancak bu kodu iyileştirebilirsiniz. Görüntülenecek kod ile görünüm tutucuları yönetme kodu karıştırılmış ve onBindViewHolder(), ViewHolder güncelleme hakkında ayrıntılı bilgiye sahip.
Üretim uygulamasında birden fazla görünüm tutucu, daha karmaşık bağdaştırıcılar ve değişiklik yapan birden fazla geliştirici olabilir. Kodunuzu, görünüm tutucuyla ilgili her şeyin yalnızca görünüm tutucuda olacağı şekilde yapılandırmalısınız.
1. adım: onBindViewHolder() işlevini yeniden düzenleyin
Bu adımda kodu yeniden düzenleyip tüm görünüm tutucu işlevlerini ViewHolder içine taşıyacaksınız. Bu yeniden düzenlemenin amacı, uygulamanın kullanıcıya nasıl göründüğünü değiştirmek değil, geliştiricilerin kod üzerinde çalışmasını kolaylaştırmak ve daha güvenli hale getirmektir. Neyse ki Android Studio'da bu konuda yardımcı olacak araçlar bulunur.
SleepNightAdapterbölümünde,onBindViewHolder()bölümünde, değişkeni bildirmek için kullanılan ifadeitemdışındaki her şeyi seçin.- Sağ tıklayın, ardından Yeniden düzenle > Ayıkla > İşlev'i seçin.
- İşlevi
bindolarak adlandırın ve önerilen parametreleri kabul edin. Tamam'ı tıklayın.bind()işlevi,onBindViewHolder()'nin altına yerleştirilir.
private fun bind(holder: ViewHolder, item: SleepNight) {
val res = holder.itemView.context.resources
holder.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)
holder.quality.text = convertNumericQualityToString(item.sleepQuality, res)
holder.qualityImage.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
})
}- İmleci,
bind()parametresininholderkelimesinin üzerine getirin.holderAmacınıza uygun menüyü açmak içinAlt+Enter(Mac'teOption+Enter) tuşuna basın. Bunu aşağıdaki imzaya sahip bir uzantı işlevine dönüştürmek için Parametreyi alıcıya dönüştür'ü seçin:
private fun ViewHolder.bind(item: SleepNight) {...}bind()işlevini kesipViewHolderaralığına yapıştırın.bind()herkese açık hâle getirin.- Gerekirse
bind()öğesini adaptöre aktarın. - Artık
ViewHolderiçinde olduğu için imzanınViewHolderbölümünü kaldırabilirsiniz.ViewHoldersınıfındakibind()işlevinin son kodu aşağıda verilmiştir.
fun bind(item: SleepNight) {
val res = itemView.context.resources
sleepLength.text = convertDurationToFormatted(
item.startTimeMilli, item.endTimeMilli, res)
quality.text = convertNumericQualityToString(
item.sleepQuality, res)
qualityImage.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: onCreateViewHolder'ı yeniden düzenleyin
Adaptördeki onCreateViewHolder() yöntemi, şu anda ViewHolder için görünümü düzen kaynağındaki görünümden şişiriyor. Ancak enflasyonun adaptörle hiçbir ilgisi yoktur ve her şey ViewHolder ile ilgilidir. Enflasyon ViewHolder içinde gerçekleşmelidir.
onCreateViewHolder()bölümünde, işlevin gövdesindeki tüm kodu seçin.- Sağ tıklayın, ardından Yeniden düzenle > Ayıkla > İşlev'i seçin.
- İşlevi
fromolarak adlandırın ve önerilen parametreleri kabul edin. Tamam'ı tıklayın. - İmleci işlev adının üzerine getirin
from. Amacınıza uygun menüyü açmak içinAlt+Enter(Mac'teOption+Enter) tuşuna basın. - Yardımcı nesneye taşı'yı seçin.
from()işlevinin,ViewHoldersınıfında çağrılabilmesi için yardımcı nesnede olması gerekir.ViewHolderörneğinde çağrılamaz. companionnesnesiniViewHoldersınıfına taşıyın.from()herkese açık hâle getirin.onCreateViewHolder()içinde,returnifadesiniViewHoldersınıfındafrom()çağrısının sonucunu döndürecek şekilde değiştirin.
TamamlanmışonCreateViewHolder()vefrom()yöntemleriniz aşağıdaki koda benzemeli ve kodunuz hatasız olarak oluşturulup çalıştırılmalıdır.
override fun onCreateViewHolder(parent: ViewGroup, viewType:
Int): ViewHolder {
return ViewHolder.from(parent)
}companion object {
fun from(parent: ViewGroup): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night, parent, false)
return ViewHolder(view)
}
}ViewHoldersınıfının imzasını, oluşturucunun özel olacak şekilde değiştirin.from()artık yeni birViewHolderörneği döndüren bir yöntem olduğundan kimseninViewHolderoluşturucusunu çağırmasına gerek kalmadı.
class ViewHolder private constructor(itemView: View) : RecyclerView.ViewHolder(itemView){- Uygulamayı çalıştırın. Uygulamanız, yeniden düzenlemeden sonraki istenen sonuç olarak eskisi gibi derlenip çalıştırılmalıdır.
Android Studio projesi: RecyclerViewFundamentals
- Android'de en sık kullanılan kullanıcı arayüzü görevlerinden biri, veri listesi veya ızgarası görüntülemektir.
RecyclerView, çok büyük listeleri görüntülerken bile verimli olacak şekilde tasarlanmıştır. RecyclerViewyalnızca ekranda görünür durumda olan öğeleri işlemek veya çizmek için gereken işlemleri yapar.- Ekranın dışına kaydırılan öğelerin görünümleri geri dönüştürülür. Bu durumda, öğe ekrana kaydırılan yeni içerikle doldurulur.
- Yazılım mühendisliğinde adaptör deseni, bir nesnenin başka bir API ile birlikte çalışmasına yardımcı olur.
RecyclerView, uygulama verilerini görüntüleyebileceği bir şeye dönüştürmek için bir bağdaştırıcı kullanır. Bu işlem için uygulamanın verileri depolama ve işleme şeklinin değiştirilmesi gerekmez.
Verilerinizi RecyclerView içinde göstermek için aşağıdaki bölümlere ihtiyacınız vardır:
- RecyclerView
:RecyclerViewörneği oluşturmak için düzen dosyasında<RecyclerView>öğesini tanımlayın. - LayoutManager
ARecyclerView,RecyclerViewiçindeki öğelerin düzenini (ör. öğeleri bir ızgarada veya doğrusal bir listede düzenleme) organize etmek içinLayoutManagerkullanır.
Düzen dosyasındaki<RecyclerView>içinde,app:layoutManagerözelliğini düzen yöneticisine (ör.LinearLayoutManagerveyaGridLayoutManager) ayarlayın.RecyclerViewiçinLayoutManagerdeğerini programatik olarak da ayarlayabilirsiniz. (Bu teknik, sonraki bir codelab'de ele alınacaktır.) - Her öğe için düzen
Bir XML düzen dosyasında bir veri öğesi için düzen oluşturun. - Adaptör
Verileri hazırlayan veViewHolderiçinde nasıl görüntüleneceğini belirleyen bir adaptör oluşturun. AdaptörüRecyclerViewile ilişkilendirin.RecyclerViewçalıştırıldığında verilerin ekranda nasıl gösterileceğini belirlemek için bağdaştırıcıyı kullanır.
Bağdaştırıcı, aşağıdaki yöntemleri uygulamanızı gerektirir:
– Öğelerin sayısını döndürmek içingetItemCount().
– Listedeki bir öğeninViewHolderdeğerini döndürmek içinonCreateViewHolder().
– Listedeki bir öğenin verilerini görünümlere uyarlamak içinonBindViewHolder(). - ViewHolder
: BirViewHolder, öğe düzeninden bir öğeyi görüntülemek için görünüm bilgilerini içerir. - Adaptördeki
onBindViewHolder()yöntemi, verileri görünümlere uyarlar. Bu yöntemi her zaman geçersiz kılarsınız. GenellikleonBindViewHolder(), bir öğenin düzenini şişirir ve verileri düzendeki görünümlere yerleştirir. RecyclerViewveriler hakkında hiçbir şey bilmediğinden, bu veriler değiştiğindeAdapter,RecyclerView'yı bilgilendirmelidir. Verilerin değiştiğiniAdapterbildirmek içinnotifyDataSetChanged()kullanın.
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
RecyclerView öğeleri nasıl gösterir? Uygun olan tüm seçenekleri işaretleyin.
▢ Öğeleri listede veya ızgarada gösterir.
▢ Dikey veya yatay olarak kaydırılır.
▢ Tablet gibi daha büyük cihazlarda çapraz kaydırılır.
▢ Liste veya ızgara kullanım alanı için yeterli olmadığında özel düzenlere izin verir.
2. Soru
RecyclerView kullanmanın avantajları nelerdir? Uygun olan tüm seçenekleri işaretleyin.
▢ Büyük listeleri verimli bir şekilde gösterir.
▢ Verileri otomatik olarak günceller.
▢ Bir öğe güncellendiğinde, silindiğinde veya listeye eklendiğinde yenileme ihtiyacını en aza indirir.
▢ Ekranı kaydırarak görüntüden çıkan görünümü, ekranda kaydırılan bir sonraki öğeyi göstermek için yeniden kullanır.
3. Soru
Adaptör kullanmanın nedenleri nelerdir? Uygun olan tüm seçenekleri işaretleyin.
▢ İlgi alanlarının ayrılması, kodun değiştirilmesini ve test edilmesini kolaylaştırır.
▢ RecyclerView, gösterilen verilerden bağımsızdır.
▢ Veri işleme katmanları, verilerin nasıl görüntüleneceğiyle ilgilenmek zorunda değildir.
▢ Uygulama daha hızlı çalışır.
4. Soru
Aşağıdakilerden hangisi ViewHolder için doğrudur? Uygun olan tüm seçenekleri işaretleyin.
▢ ViewHolder düzeni, XML düzen dosyalarında tanımlanır.
▢ Veri kümesindeki her veri birimi için bir ViewHolder vardır.
▢ Bir RecyclerView içinde birden fazla ViewHolder olabilir.
▢ Adapter, verileri ViewHolder'ye bağlar.
Bir sonraki derse başlayın: