Android RecyclerView: Nedir, Basit Örneklerle Öğrenin

⚡ Akıllı Özet

RecyclerView gelişmiş bir üründür. Android Sınırlı sayıda görünümü yeniden kullanarak büyük, kaydırılabilir veri kümelerini verimli bir şekilde görüntüleyen bir widget. Çalışma zamanında değişen veri koleksiyonlarını bağlamak için bir adaptör, bir düzen yöneticisi ve bir görünüm tutucuya dayanır.

  • ???? Ne olduğunu: RecyclerView, büyük veri kümelerini görüntülemek için ListView ve GridView'ın esnek bir halefidir.
  • 🧱 Görünümler ve Görünüm Grupları: Android Arayüzü View ve ViewGroup sınıflarını kullanarak çizer; LayoutParams ise boyut ve konumu kontrol eder.
  • 🔄 Adaptörü: Adaptör deseni, bir veri dizisini RecyclerView'ın kabul edebileceği ViewHolder'lara dönüştürür.
  • 📐 Düzen Yöneticisi: Yerleşim yöneticisi, öğeleri doğrusal veya ızgara şeklinde düzenler ve görünümlerin ne zaman yeniden kullanılabileceğini belirtir.
  • ♻️ Geri dönüşüm: Ekran dışı görüntüler yeniden oluşturulmak yerine tekrar kullanılır, bu da bellekten tasarruf sağlar ve kaydırma işleminin sorunsuz devam etmesini sağlar.
  • Adımları oluşturun: Eklemek Gradle Bağımlılık oluşturmak için bir öğe düzeni, bir ViewHolder, bir adaptör ve bir LayoutManager oluşturun.

Android Geri Dönüşüm Görünümü

RecyclerView nedir? Android?

MKS Geri Dönüşüm Görünümü RecyclerView, GridView ve ListView'in daha esnek ve gelişmiş bir versiyonudur. Sınırlı sayıda görünüm koruyarak verimli bir şekilde kaydırılabilen büyük veri kümelerini görüntülemek için kullanılan bir kapsayıcıdır. Öğeleri ağ olayına veya kullanıcı eylemine bağlı olarak çalışma zamanında değişen veri koleksiyonlarınız olduğunda RecyclerView widget'ını kullanabilirsiniz.

Görünümler

MKS Android Platform, ekrana öğeler çizmek için View ve ViewGroup sınıflarını kullanır. Bu sınıflar mutlaktracTextView ve EditText, kullanım senaryosuna uygun farklı uygulamalara genişletilir. Örneğin, TextView'in basit amacı ekranda metin içeriği görüntülemektir. EditText ise aynı View sınıfından türetilir ve kullanıcının veri girmesini sağlamak için daha fazla işlevsellik ekler.

Geliştirme sürecinde daha fazla esneklik sağlamak için kendi özel görünümlerimizi oluşturmak mümkündür.ping Kullanıcı arayüzleri. View sınıfı, ekrana çizim yapmak için geçersiz kılabileceğimiz yöntemler ve genişlik, yükseklik ve View'e eklemek istediğimiz kendi özel niteliklerimiz gibi parametreleri iletme olanağı sağlar; böylece View istediğimiz gibi davranır.

Grupları Görüntüle

ViewGroup sınıfı bir tür View'dir, ancak basit View sınıfının sorumluluğu yalnızca görüntülemekken, ViewGroup bize birden fazla görünümü tek bir görünüme yerleştirme ve bu görünümü bir bütün olarak referans alma olanağı sağlar. Bu durumda, diğer basit görünümleri eklediğimiz en üst düzeyde oluşturulan görünüme "ebeveyn", içine eklenen görünümlere ise "çocuk" denir.

Bir View'ı bir Dizi, bir ViewGroup'u ise Dizilerden oluşan bir Dizi olarak düşünebiliriz. Dizilerden oluşan bir Dizinin kendisinin de bir Dizi olduğunu göz önünde bulundurarak, bir ViewGroup'un nasıl bir View gibi ele alınabileceğini görebiliriz.

var arr1 = [1,2,3] //imagine a simple View as an Array
//we can imagine this as a NumberTextView which doesn't really exist
//but we could imagine there's one that makes it easy to use numbers
var arr2 = ["a","b","c"] // We can imagine this as another simple view

var nestedArr = [arr1,arr2] //in our analogy, we can now group views
//together and the structure that would hold that would be what we call the ViewGroup

ViewGroup ayrıca, alt öğelerin görünüm içinde nasıl düzenleneceğini, örneğin dikey mi yoksa yatay mı yerleştirileceklerini tanımlamamızı sağlar. Görünüm içindeki etkileşim için farklı kurallar belirleyebiliriz. Örneğin, birbirini takip eden TextView'ler arasında 12dp mesafe olmalı, bir TextView'i takip eden ImageView arasında ise 5dp mesafe olmalıdır.

Eğer biz geliştirseydik durum böyle olurdu.ping Kendi ViewGroup'umuzu sıfırdan oluşturduk. Bu yapılandırmaları kolaylaştırmak için, Android bu konfigürasyonları girmek için kullanabileceğimiz LayoutParams adında bir sınıf sağlar.

MKS Android belgeleme Bu, kendi ViewGroup'umuzu yapılandırırken uygulayacağımız bazı varsayılan parametreler sağlar. Bazı yaygın parametreler genişlik, yükseklik ve kenar boşluğu ile ilgilidir. Varsayılan olarak, bu yapılandırmalar yükseklik için android:layout_height ve genişlik için android:layout_width yapısına sahiptir. Bu bağlamda, ViewGroup'unuzu oluştururken, ViewGroup'unuzun nasıl davranmasını istediğinize özgü LayoutParams'lar da oluşturabilirsiniz.

Android Varsayılan olarak birçok yaygın görevi yerine getirmek için kullanabileceğimiz Görünümler ve Görünüm Grupları ile birlikte gelir. Bahsettiğimiz örneklerden biri TextView'dir. Bu, yükseklik, genişlik ve metin boyutu gibi yapılandırılabilir özelliklere sahip basit bir görünümdür. Ayrıca, bahsettiğimiz gibi, resimleri görüntülemek için bir ImageView ve EditText'imiz de var. Android ayrıca Görünümlerimizi ekleyebileceğimiz ve beklenen davranışı alabileceğimiz özel ViewGroup'lara da sahiptir.

Doğrusal Düzen

LinearLayout, içine View öğeleri eklememizi sağlar. LinearLayout'ın, ekranda nasıl yerleştirileceğini belirleyen bir orientation özniteliği vardır. Ayrıca, içindeki View'ler için kuralları belirleyen LinearLayout.LayoutParams özniteliğine de sahiptir. Örneğin, android:center_horizontal özniteliği View'leri yatay eksen boyunca ortalar, android:center_vertical ise View'in içeriğini dikey eksen boyunca ortalar.

Merkezleme özelliğini anlamanıza yardımcı olacak bazı görseller aşağıda verilmiştir. Bunu 200px x 200px'lik bir alanda bulunan basit bir TextView olarak ele alıyoruz; merkezleme öznitelikleri, aşağıdaki gibi davranmasını sağlayacaktır.

android:orta_yatay

Yatay Olarak Ortalanmış İçerik

Yatay olarak ortalanmış içerik

android:center_dikey

Dikey Olarak Ortalanmış İçerik

Dikey olarak ortalanmış içerik

android:merkez

Ortalanmış İçerik

Ortalanmış içerik

RecyclerView'ın Temel Bileşenleri

RecyclerView'ın Temel Bileşenleri

RecyclerView'ın Temel Bileşenleri

RecyclerView'un önemli bileşenleri şunlardır:

RecyclerView.Adapter

Temel Çalışması #1 – Adaptör Kalıbı

Adaptör, bir sistemin veya cihazın özelliklerini, aksi takdirde uyumsuz olan başka bir cihazın veya sistemin özelliklerine dönüştüren bir aygıttır. Bazı adaptörler sinyal veya güç özelliklerini değiştirirken, diğerleri yalnızca bir konektörün fiziksel biçimini diğerine uyarlar.

Adaptörün ne işe yaradığını açıklayan basit bir gerçek hayat örneği, cihazları birbirine bağlamamız gerektiğinde ancak bağlantı noktalarının birbirine uymadığı durumlardır. Bu durum, farklı priz türleri kullanan farklı bir ülkeyi ziyaret ettiğinizde ortaya çıkabilir. Telefonunuzun veya dizüstü bilgisayarınızın şarj cihazını yanınızda taşıyorsanız, onu elektrik prizlerine bağlamak imkansız olacaktır. Ancak, pes etmezsiniz ve priz ile şarj cihazınız arasına giren ve şarj işlemini mümkün kılan bir adaptör alırsınız.

Bu durum, programlamada iki veri yapısını bir görevi yerine getirmek için birbirine bağlamak istediğimizde, ancak varsayılan bağlantı noktalarının birbirleriyle iletişim kurma yolu olmadığında ortaya çıkar.

Basit bir örnek olarak bir cihaz ve bir şarj aleti kullanacağız. İki farklı şarj aleti örneğimiz olacak: biri Amerikan tipi, diğeri İngiliz tipi.

class AmericanCharger() {
    var chargingPower = 10
}
class BritishCharger(){
    var chargingPower = 5
}

Ardından iki cihaz oluşturacağız.

class AmericanDevice()
class BritishDevice()

Örnek olarak, birlikte oynamak için cihazların bazı örneklerini oluşturabiliriz.

var myAmericanPhone = new AmericanDevice()
var myBritishPhone = new BritishDevice()

Daha sonra, cihazlara charge() adında bir metot ekleyerek her iki cihaz için de şarj etme kavramını tanıtacağız. Bu metot, ilgili şarj cihazını alır ve ona göre şarj işlemini gerçekleştirir.

sealed trait Device
class AmericanDevice : Device{
    fun charge(charger:AmericanCharger){
        //Do some American charging
    }
}
class BritishDevice: Device{
    fun charge(charger:BritishCharger){
        //Do some British charging
    }
}

Bu durumda, analojimize dayanarak, bir nedenden dolayı Amerikan cihazı kullanırken İngiliz şarj cihazı kullanmamız veya tam tersi durum söz konusu olabilir.

Programlama dünyasında bu genellikle aynı işlevselliği sunan kitaplıkları bir araya getirirken gerçekleşir (bizim bağlamımızda, ortak işlevselliğimiz ücrete tabidir). Bunu etkinleştirmenin bir yolunu bulmamız gerekecek.

Analojiyi takip edersek, bir elektronik mağazasına gidip, İngiliz şarj cihazları kullanarak Amerikan cihazlarını şarj etmemizi sağlayacak bir adaptör satın almamız gerekecek. Programlama açısından bakıldığında, adaptörün üreticisi biz olacağız.

Diğerini oluşturmak için ihtiyaç duyacağımız tam kalıba uyan bir adaptör oluşturacağız. Bunu aşağıdaki gibi bir sınıf olarak uygulayacağız. İlla bir sınıf olması gerekmez ve adaptör kalıbının genel olarak ne yaptığını vurgulayan bir fonksiyon da olabilir. Sınıf kullanmamızın nedeni, çoğu kullanımda bu şekilde eşleşmesidir. Android.

class AmericanToBritishChargerAdapter(theAmericanCharger:AmericanCharger){
    fun returnNewCharger(): BritishCharger{
            //convert the American charger to a BritishCharger
            //we would change the American charging functionality
            //to British charging functionality to make sure the
            //adapter doesn't destroy the device. The adapter could
            //, for example, control the power output by dividing by 2
            //our adapter could encompass this functionality in here

           var chargingPower:Int = theAmericanCharger.chargingPower / 2
           var newBritishCharger = new BritishCharger()
           newBritishCharger.chargingPower = theAmericanCharger.chargingPower/2

        return newBritishCharger
    }
}

Programlama dünyasında, soketler arasındaki fark, şarj etme yöntemlerindeki farklılığa benzer. Farklı şarj yöntemlerine sahip şarj cihazları, kullanılmalarını imkansız hale getirir.

var myBritishDevice = new BritishDevice()
var americanChargerIFound = new AmericanCharger()

myBritishDevice üzerinde charge() yöntemini americanChargerIFound ile çağırmaya çalışmak işe yaramaz, çünkü AmericanDevice yalnızca AmericanCharger kabul eder. Bu nedenle bunu yapmak imkansızdır:

var myBritishDevice = new BritishDevice()
var americanChargerIFound = new AmericanCharger()
myBritishDevice.charge(americanChargerIFound)

Bu senaryoda, oluşturduğumuz AmericanToBritishChargerAdapter adaptörümüz artık işimize yarayabilir. Yeni bir BritishCharger oluşturmak için returnNewCharger() yöntemini kullanabiliriz ve bunu şarj etmek için kullanabiliriz. Tek yapmamız gereken adaptörümüzün bir örneğini oluşturmak ve ona sahip olduğumuz AmericanCharger'ı vermek; böylece kullanabileceğimiz bir BritishCharger oluşturulacaktır.

var myBritishDevice = new BritishDevice()
var americanChargerIFound = new AmericanCharger()
//We create the adapter and feed it the americanCharger
var myAdapter =  AmericanToBritishChargerAdapter(americanChargerIFound)
//calling returnNewCharger from myAdapter would return a BritishCharger
var britishChargerFromAdapter = myAdapter.returnNewCharger()
//and once we have the britishCharger we can now use it
myBritishDevice.charge(britishChargerFromAdapter)

RecyclerView.LayoutManager

ViewGroup'larla çalışırken, içlerinde View'lar bulunur. LayoutManager'ın görevi ise View'ların içlerinde nasıl yerleştirileceğini tanımlamaktır.

Karşılaştırma yapmak gerekirse, LinearLayout ViewGroup ile çalışırken istediğimiz kullanım senaryosu, öğeleri dikey veya yatay olarak yerleştirme yeteneğidir. Bu, LinearLayout'un ekranda nasıl yerleştirileceğini bize söyleyen bir yönlendirme özniteliği ekleyerek kolayca uygulanabilir. Bunu şu şekilde yapabiliriz: android:orientation=VERTICAL|HORIZONTAL özniteliği.

Ayrıca GridLayout adında başka bir ViewGroup'umuz daha var. Kullanım alanı, View'ları dikdörtgen bir ızgara yapısına yerleştirmek istediğimiz zamanlardır. Bunun nedeni, uygulama kullanıcısına sunduğumuz verilerin kolayca tüketilebilir olmasını sağlamak gibi olabilir. Tasarım gereği, GridLayout, ızgaranın boyutlarını tanımlayarak bu hedefe ulaşmanıza yardımcı olacak yapılandırmalar sunar; örneğin, 4x4 veya 3x2'lik bir ızgaraya sahip olabiliriz.

RecyclerView.ViewHolder

ViewHolder bir abs'dir.tracRecyclerView'dan türettiğimiz bir sınıf olan ViewHolder, RecyclerView'a yerleştirdiğimiz bir View'a, RecyclerView'daki geri dönüşüm mekanizmasının bilmediğimiz çeşitli referansları değiştirmesinden sonra bile, referans vermemize yardımcı olacak ortak yöntemler sağlar.

Büyük Listeler

RecyclerView'lar, kullanıcıya gerçekten çok sayıda görünüm sunmak istediğimizde, ancak aynı zamanda kaynak havuzunu tüketmemek istediğimizde kullanılır. RAM Oluşturulan Görünümün her bir örneği için cihazımızda.

Bir kişi listesi örneğini ele alırsak, listedeki bir kişinin nasıl görüneceğine dair genel bir fikrimiz olur. Daha sonra yapacağımız şey, kişi listemizdeki çeşitli verilerin doldurulacağı yuvalara sahip bir şablon düzeni (aslında bir Görünüm) oluşturmaktır. Aşağıda, tüm amacı açıklayan sözde kod bulunmaktadır:

//OneContactView
<OneContact>
<TextView>{{PlaceHolderForName}}</TextView>
<TextView>{{PlaceHolderForAddress}}</TextView>
<ImageView>{{PlaceHolderForProfilePicture}}</ImageView>
<TextView>{{PlaceHolderForPhoneNumber}}</TextView>
</OneContact>

O zaman elimizde şu şekilde bir İletişim Listesi olurdu:

<ContactList>
</ContactList>

İçeriği kod içine doğrudan yazsaydık, uygulamayı yeniden yazmadan listeye yeni içerik eklemenin programatik bir yolunu bulamazdık. Neyse ki, bir ViewGroup'a View eklemek, bir yöntemle destekleniyor. addView(view:View) Bu yöntemle RecyclerView'a alt görünümler eklenmez. Ancak yine de, RecyclerView'a alt görünümler bu şekilde eklenmez.

Bizim kullanım senaryomuzda, uzun bir kişi listemiz olacak. Listedeki her kişi için bir OneContactView oluşturmamız ve bu görünümün içindeki verileri Contact sınıfımızdaki alanlarla eşleşecek şekilde doldurmamız gerekecek. Ardından, görünümü oluşturduktan sonra, listeyi göstermek için onu RecyclerView'a eklememiz gerekecek.

data  class Contact(var name:String, var address:String, var pic:String, var phoneNumber:Int)

var contact1 = Contact("Guru","Guru97", "SomePic1.jpg", 991)
var contact2 = Contact("Guru","Guru98", "SomePic2.jpg", 992)
var contact3 = Contact("Guru","Guru99", "SomePic3.jpg", 993)

var myContacts:ArrayList<Contact> = arrayListOf<Contact>(contact1,contact2,contact3)

Elimizde bir iletişim listesi var. OneContactView, Contact sınıfından içerik alıp bunları görüntülemek için yuvalar içeriyor. RecyclerView'da ise, geri dönüşüm özelliğine yardımcı olabilmesi için içine View'lar eklememiz gerekiyor.

RecyclerView aslında bize bir görünüm ekleme olanağı sağlamaz, ancak bir ViewHolder eklememizi sağlar. Dolayısıyla, bu senaryoda, birbirine bağlamak istediğimiz ancak eşleşmeyen iki parçamız var. İşte burada adaptörümüz devreye giriyor. RecyclerView bize, tıpkı bizimki gibi bir adaptör sağlar. AmericanToBritishChargerAdapter() Daha önce edindiğimiz bir bilgi sayesinde, İngiliz cihazımızla kullanılamayan Amerikan şarj cihazımızı, gerçek hayattaki bir güç adaptörüne benzer şekilde, kullanılabilir bir şeye dönüştürebildik.

Bu senaryoda, adaptör iletişim bilgilerimizden oluşan diziyi ve Görünümümüzü alacak ve buradan RecyclerView'ın kabul edeceği ViewHolder'lar oluşturacaktır.

RecyclerView, RecyclerView.Adapter sınıfı aracılığıyla adaptörümüzü oluşturmak için genişletebileceğimiz bir arayüz sağlar. Bu adaptörün içinde, RecyclerView'ın çalışmak istediği ViewHolder sınıfını oluşturmanın bir yolu bulunur. Yani, öncekiyle aynı duruma sahibiz, ancak bir ekstra şey daha var: adaptör.

Kişi listemiz, bir kişiyi görüntüleyen bir görünüm (OneContactView) ve geri dönüşüm hizmetleri sağlayan ancak yalnızca ViewHolder'ları kabul eden bir Görünüm listesi olan bir RecyclerView'ımız var. Bu senaryoda, içinde ViewHolder'lar oluşturmak için bir metoda sahip bir RecyclerView.Adapter sınıfımız var.

fun createViewHolder(@NonNull parent: ViewGroup, viewType: Int): ViewHolder

RecyclerView.ViewHolder bir abs'dir.tracView'ımızı argüman olarak alan ve onu ViewHolder'a dönüştüren bir sınıftır. Sınıfların yeteneklerini genişletmek için kullanılan sarmalayıcı desenini kullanır.

Temel Çalışması #2 – Sarma deseni

Hayvanların nasıl konuşabileceğini göstermek için basit bir örnek kullanacağız.

sealed trait Animal{
    fun sound():String
}

data class Cat(name:String):Animal{
    fun sound(){
        "Meow"
        }
}
data class Dog(name:String):Animal{
    fun sound(){
        "Woof"
        }
}

var cat1 = Cat("Tubby")
var dog1 = Dog("Scooby")
cat1.sound() //meow
dog1.sound() //woof

Yukarıdaki örnekte iki hayvanımız var. Eğer, diyelim ki, onlara konuşma özelliği ekleyecek bir yöntem eklemek istedik ama kütüphane yazarı buna yanaşmadıysa, yine de bir yol bulabiliriz. Bunun için Hayvan sınıfımız için bir sarmalayıcıya ihtiyacımız olurdu. Bunu da Hayvan sınıfını sınıfımızın kurucusu olarak alarak yapardık.

class SpeechPoweredAnimalByWrapper(var myAnimal:Animal){

    fun sound(){
        myAnimal.sound()
    }

    fun speak(){
        println("Hello, my name is ${myAnimal.name}")
    }
}

Artık SpeechPoweredAnimalByWrapper'a bir hayvan örneği aktarabiliriz. Üzerinde sound() yöntemini çağırmak, aktarılan hayvanın sound() yöntemini çağıracaktır. Ayrıca, aktarılan hayvanlara eklediğimiz yeni bir işlevsellik olarak sayılan ek bir speak() yöntemimiz de var. Bunu şu şekilde kullanabiliriz:

var cat1 =  Cat("Garfield")
cat1.sound()//"meow"
cat1.speak()// doesn't work as it isn't implemented
var talkingCat = new SpeechPoweredAnimalByWrapper(cat1)
talkingCat.sound() //"meow" the sound method calls the one defined for cat1
talkingCat.speak() //"Hello, my name is Garfield"

Bu kalıbı kullanarak, sınıflara işlevsellik ekleyebiliriz. Tek yapmamız gereken, bir sınıf örneği ve sarmalayıcımız tarafından tanımlanan yeni yöntemleri iletmek.ping sınıf.

Yukarıdaki örnekte somut bir sınıf kullandık. Aynı şeyi soyut bir yapıda da uygulamak mümkündür.tract sınıfı. SpeechPoweredAnimalByWrapper sınıfını abs olarak değiştirmemiz gerekecek.tracVe işimiz bitti. Daha okunaklı olması için sınıf adını daha kısa bir şeyle değiştireceğiz.

abstract class SpeechPowered(var myAnimal:Animal){

    fun sound(){
        myAnimal.sound()
    }

    fun speak(){
        println("Hello, my name is ${myAnimal.name}")
    }
}

Öncekiyle aynı, ama farklı bir anlama geliyor. Normal bir sınıfta, cat1 ve dog1'i oluşturduğumuz gibi bir sınıfın örneğine sahip olabiliriz. AbstracAncak t sınıfları örneklendirilmek için değil, diğer sınıfları genişletmek için tasarlanmıştır. Peki yeni SpeechPowered(var myAnimal:Animal) abs'yi nasıl kullanırız?tracT sınıfı mı? Onu genişletecek ve dolayısıyla işlevselliğini kazanacak yeni sınıflar oluşturarak kullanabiliriz.

Örneğimizde, mevcut sınıftan türetilen SpeechPoweredAnimal adlı bir sınıf oluşturacağız.

class SpeechPoweredAnimal(var myAnimal:Animal):SpeechPowered(myAnimal)
var cat1 =  Cat("Tubby")
var speakingKitty = SpeechPoweredAnimal(cat1)
speakingKitty.speak() //"Hello, my name is Tubby"

Bu, ViewHolder'da kullanılanla aynı kalıptır. RecyclerView.ViewHolder sınıfı bir abs sınıfıdır.tracBu sınıf, tıpkı hayvanlara "speak" yöntemini eklediğimiz gibi, görünüme işlevsellik ekler. Eklenen bu işlevsellik, RecyclerView ile çalışırken görünümünün düzgün çalışmasını sağlar.

OneContactView'den OneContactViewHolder'ı şu şekilde oluşturabiliriz:

//The View argument we pass is converted to a ViewHolder which uses the View to give it more abilities and in turn work with the RecyclerView
class OneContactViewHolder(ourContactView: View) : RecyclerView.ViewHolder(ourContactView)

RecyclerView'da, kişi listemizi ContactsView'a bağlamamızı sağlayan bir adaptör bulunur.

Görünüm Ekleme

ViewGroup otomatik olarak yeniden çizilmez, belirli bir programa göre yeniden çizilir. Cihazınızda her 10 ms veya 100 ms'de bir yeniden çizilebilir; veya absürt bir sayı seçersek, örneğin 1 dakika, bir View'ı ViewGroup'a eklediğimizde, ViewGroup "yenilendiğinde" değişiklikleri 1 dakika sonra görürüz.

RecyclerView.Recycler

Temel Çalışma #3 – Önbellekleme

Sayfayı düzenli olarak yenilediğimiz en iyi örneklerden biri tarayıcıdır. Örneğin, ziyaret ettiğimiz sitenin statik olduğunu ve dinamik olarak içerik göndermediğini varsayalım; değişiklikleri görmek için sürekli sayfayı yenilememiz gerekir.

Bu örnekte, söz konusu sitenin Twitter olduğunu varsayalım. Listelenen bir dizi statik tweet'imiz olurdu ve yeni tweet'leri görebilmemizin tek yolu, içeriği yeniden yüklemek için yenileme düğmesine tıklamak olurdu.

Ekranın tamamını yeniden çizmek elbette maliyetli bir işlemdir. Telefon sağlayıcımızda sınırlı bant genişliğimiz olduğunu ve tweet listemizde çok sayıda resim ve video bulunduğunu düşünün; her sayfa yenilemesinde sayfanın tüm içeriğini yeniden indirmek maliyetli olurdu.

Önceden yüklenmiş tweetleri saklamanın ve bir sonraki isteğimizin hangi tweetlere zaten sahip olduğunu belirtebilmesini sağlamanın bir yoluna ihtiyacımız var. Bu nedenle, her şeyi yeniden indirmez ve yalnızca yeni tweetleri alır; ayrıca yerel olarak kaydedilmiş bir tweetin artık orada olup olmadığını kontrol eder, böylece onu yerel olarak silebilir. Tanımladığımız şeye önbellekleme denir.

Web sitesine gönderdiğimiz içeriklerle ilgili bilgilere meta veri denir. Yani gerçek anlamda sadece "sitenizi yüklemek istiyoruz" demiyoruz, "sitenizi yüklemek istiyoruz ve işte son yüklemeden kaydettiğimiz bazı içerikler; lütfen bunları kullanarak bize yalnızca içerikte olmayanları gönderin, böylece çok fazla bant genişliği kullanmayalım" diyoruz.

Düzen Çağrıları – Tweet Listesi çılgın olmalı

Bir düzen çağrısına örnek olarak scrollToPosition verilebilir. Bu, sohbet uygulamaları gibi yerlerde sıkça karşılaşılan bir örnektir. Bir sohbet dizisinde biri daha önceki bir sohbet balonuna yanıt verirse, bazı sohbet uygulamaları yanıtı ve sohbet balonuna giden bir bağlantıyı içerir; bu bağlantıya tıkladığınızda sizi orijinal mesajınızın bulunduğu yere yönlendirir.

Eğer bu metodu, RecyclerView'a LayoutManager eklemeden ve RecyclerView.Adapter'ı oluşturmadan önce çağırırsak, scrollToPosition(n:Int) basitçe yok sayılır.

RecyclerView Bileşenleri arasındaki iletişim

Temel Çalışma #4 – Geri Çağrılar

RecyclerView, işlevini yerine getirirken birçok hareketli parçaya sahiptir. Görünümleri doğrusal veya ızgara şeklinde nasıl düzenleyeceğimizi bize söyleyen LayoutManager ile ilgilenmesi gerekir. Öğelerimizi (contactList) Görünümlere (OneContactView) ve ardından RecyclerView'ın sağladığı yöntemleri kullanarak çalışmaya istekli olduğu ViewHolder'lara (OneContactViewHolder) dönüştürme işini yapan bir adaptörle de ilgilenmesi gerekir.

RecyclerView'ın ham maddesi, OneContactView gibi Görünümlerimiz ve bir veri kaynağıdır.

contactList:Array<Contact>

RecyclerView'ın neyi başarmaya çalıştığını anlamak için basit bir senaryoyu başlangıç ​​noktası olarak kullandık. Kullanıcıya göstermek istediğimiz 1000 kişiden oluşan statik bir dizinin olduğu temel durum kolayca anlaşılabilir. RecyclerView mekanizması, liste artık statik olmadığında gerçekten canlanmaya başlar. Dinamik bir listede, listeye bir öğe eklediğimizde veya listeden bir öğe çıkardığımızda ekrandaki görünümde neler olduğunu düşünmeliyiz.

RecyclerView.LayoutManager

LayoutManager, görünümlerimizin doğrusal veya ızgara şeklinde nasıl yerleştirileceğine karar vermenin yanı sıra, arka planda birçok işi de hallediyor.ping Geri dönüştürücü, geri dönüşümü ne zaman yapacağını bilir.

Bu, korumaktan sorumludur.ping tracLayoutManager, ekranda şu anda görünür olan Görünümlerin sayısını belirler ve bu bilgiyi geri dönüşüm mekanizmasına iletir. Kullanıcı aşağı doğru kaydırdıkça, LayoutManager, üst kısımda odak dışı kalan Görünümleri geri dönüşüm sistemine bildirmekten sorumludur; böylece bu Görünümler orada kalıp bellek tüketmek veya yalnızca yenilerini oluşturmak için yok edilmek yerine yeniden kullanılabilirler.

Bu, LayoutManager'ın bunu saklaması gerektiği anlamına gelir. tracKullanıcı listede gezinirken bulunduğu konumu gösterir. Bunu, indeks tabanlı bir konum listesi oluşturarak yapar; yani ilk öğe 0'dan başlar ve listedeki öğe sayısına uyacak şekilde artar.

Diyelim ki 100 öğeden oluşan listemizden 10 öğeyi görüntüleyebiliyoruz; başlangıçta LayoutManager, View-0'dan View-9'a kadar tüm görünümlerin odak noktasında olduğunu bilir. Kaydırma işlemi sırasında LayoutManager, odak noktasının dışına çıkan görünümleri hesaplayabilir.

LayoutManager, bu görünümleri geri dönüşüm mekanizmasına bırakarak yeniden kullanılmalarını sağlayabilir (yeni veriler bunlara bağlanabilir; örneğin, bir görünümün iletişim verileri kaldırılabilir ve bir sonraki segmentten gelen yeni iletişim verileri yer tutucuların yerini alabilir).

Liste statik olsaydı bu ideal bir durum olurdu, ancak RecyclerView'ın en yaygın kullanım alanlarından biri, verilerin çevrimiçi bir uç noktadan veya hatta bir sensörden gelebildiği dinamik listelerdir. Sadece veri eklenmez, aynı zamanda listemizdeki veriler bazen kaldırılır veya güncellenir.

Verilerimizin dinamik durumu, LayoutManager hakkında mantık yürütmeyi oldukça zorlaştırabilir. Bu nedenle, LayoutManager, geri dönüşüm bileşeninin kullandığı listeden ayrı olarak, öğeler ve konumlar hakkında kendi listesini tutar. Bu, düzenleme işini doğru bir şekilde yapmasını sağlar.

Aynı zamanda, RecyclerView'ın LayoutManager'ı elindeki verileri yanlış temsil etmek istemez. Doğru çalışabilmesi için LayoutManager, belirli aralıklarla (60 ms) RecyclerView.Adapter ile senkronize olur ve eklenen, güncellenen, kaldırılan veya bir konumdan diğerine taşınan öğeler gibi liste öğeleri hakkında bilgi paylaşır. LayoutManager, bu bilgiyi aldıktan sonra, gerektiğinde ekrandaki içeriği değişikliklere uyacak şekilde yeniden düzenler.

RecyclerView ile ilgili temel işlemlerin çoğu, bazen statik bazen de dinamik verilerden oluşan listelerimizi saklayan RecyclerView.LayoutManager ve RecyclerView.Adapter arasındaki iletişim etrafında döner.

Ayrıca, RecyclerView bize olayları dinlemek için kullanabileceğimiz yöntemler sunar; örneğin, RecyclerView.Adapter'ımız listedeki içeriği (örneğin bir kişiyi) bir ViewHolder'a bağladığında ve bu sayede bilgilerin ekranda görüntülenmesinde kullanıldığında, onBindViewHolder yöntemi devreye girer.

Bir diğeri ise onCreateViewHolder'dır; bu yöntem, RecyclerView.Adapter'ın OneContactView gibi normal bir View'ı alıp RecyclerView'ın çalışabileceği bir ViewHolder öğesine dönüştürdüğü zamanı bize bildirir.

Geri dönüşümü sağlayan temel mekanizmaların yanı sıra, RecyclerView, geri dönüşümü etkilemeden davranışı özelleştirmenin yollarını da sunar. Görünümlerin yeniden kullanımı, statik görünümlerle yapmaya alışkın olduğumuz yaygın şeyleri, örneğin onClick olaylarına tepki vermeyi zorlaştırır.

Bildiğimiz gibi, RecyclerView.LayoutManager Görünümleri kullanıcıya sunan öğe bir an için öncekinden farklı bir öğe listesine sahip olabilir. RecyclerView.Adapter Bu, listeyi bir veritabanında saklayan veya bir kaynaktan akış halinde alan bir yapıdır. OnClick olaylarını doğrudan View'lara eklemek, yanlış kişiyi silmek gibi beklenmedik davranışlara yol açabilir.

Gradle

RecyclerView kullanmak istiyorsak, bunu build.gradle dosyamıza bağımlılık olarak eklememiz gerekiyor. Aşağıdaki örnekte, bu makaleye göre en güncel sürüm olan "androidx.recyclerview:recyclerview:1.1.0" uygulamasını kullandık.

Bağımlılığımızı ekledikten sonra Gradle dosya, bizden istenecek Android Studio Değişiklikleri senkronize etmek için. Bizim yöntemimiz bu şekilde. Gradle Bu dosya, varsayılan ayarlarla boş bir projeye RecyclerView ekledikten sonraki işlemleri yönetecektir.

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.guru99.learnrecycler"
        minSdkVersion 17
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
             'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    implementation "androidx.recyclerview:recyclerview:1.1.0"
}

Şu an için yalnızca bir düzen dosyamız var. Ekranda meyve isimlerinin listesini göstermek için RecyclerView kullandığımız basit bir örnekle başlayacağız.

Eşyaların listesi

Kurulum sırasında oluşturulan onCreate() metodundan hemen önce, MainActivity dosyamıza gidip içine meyve isimlerinin bulunduğu bir dizi oluşturacağız.

package com.guru99.learnrecycler

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

    var fruitNames:Array<String> = arrayOf<String>("Banana", "Mango", "Passion fruit", "Orange", "Grape")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

Bir sonraki hedefimiz, bu listeyi bir RecyclerView kullanarak ekranda göstermek olacak. Bunu yapmak için, düzenlerimizi içeren düzen dizinine gideceğiz ve bir meyveyi göstermekten sorumlu olacak bir Görünüm oluşturacağız.

Listemizdeki her öğe için kullanılacak düzen

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fruitName"
    />
</TextView>

Yukarıdaki TextView'de, bir View'i tanımlamak için kullanılacak bir id alanı ekledik. Bu alan varsayılan olarak oluşturulmaz. TextView'imize, ona bağlanacak verilerle eşleşmesi için fruitName id'sini verdik.

RecyclerView'ı ana düzene ekleme

Aynı etkinlikte, varsayılan olarak bizim için oluşturulmuş bir main_layout.xml düzen dosyası bulunmaktadır. Boş bir proje seçersek, bu dosya otomatik olarak oluşturulacaktır. XML İçinde "Merhaba" yazısı bulunan bir TextView'in yer aldığı bir ConstraintLayout oluşturacağız. Tüm içeriği sileceğiz ve düzen yalnızca aşağıdaki gibi RecyclerView'ı içerecek şekilde kalacak:

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView 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:id="@+id/fruitRecyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" />

Ayrıca, kodumuzda ona referans vermek için kullanacağımız bir id özniteliği de ekledik.

android:id="@+id/fruitRecyclerView"

Ardından MainActivity dosyamıza geri döneceğiz. Oluşturduğumuz kimlikleri kullanarak, az önce oluşturduğumuz Görünümleri referans alabileceğiz. İlk olarak, sağlanan findViewById() yöntemini kullanarak RecyclerView'ı referans alacağız. AndroidBunu onCreate() metodumuzda yapacağız. onCreate() metodumuz şu şekilde görünecektir.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)
}

Bir ViewHolder oluşturun

Ardından, görünümümüzü alıp RecyclerView'ın öğelerimizi görüntülemek için kullandığı bir ViewHolder'a dönüştürmekten sorumlu olan bir RecyclerView.ViewHolder oluşturacağız. Bunu onCreate() yöntemimizden hemen sonra yapacağız.

package com.guru99.learnrecycler

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {

    var fruitNames:Array<String> = arrayOf<String>("Banana", "Mango", "Passion fruit", "Orange", "Grape")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)
    }

    class FruitViewHolder(fruitView: View): RecyclerView.ViewHolder(fruitView)

}

RecyclerViewAdapter oluşturun

Ardından, RecyclerView.Adapter sınıfını genişleten bir FruitArrayAdapter sınıfı oluşturacağız. Oluşturacağımız FruitArrayAdapter şu görevlerden sorumlu olacak: meyve dizisinden meyve adlarını alacak, one_fruit_view.xml görünümümüzü kullanarak bir ViewHolder oluşturacak, daha sonra meyveyi ViewHolder'a bağlayacak ve içeriğini dinamik olarak oluşturduğumuz Görünüme bağlayacaktır.

package com.guru99.learnrecycler

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {

    var fruitNames:Array<String> = arrayOf<String>("Banana", "Mango", "Passion fruit", "Orange", "Grape")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)
    }

    class FruitViewHolder(fruitView: View): RecyclerView.ViewHolder(fruitView)

    class FruitArrayAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>()
}

Android Studio FruitArrayAdapter'ımıza kırmızı dalgalı çizgiler ekleyecek ve bu da RecyclerView'ın dizimizi bir ViewHolder'a bağlamak için kullanabileceği yöntemleri uygulamamız gerektiğini bize bildirecektir.

class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

     }

     override fun getItemCount(): Int {

     }

     override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

     }
 }

Oluşturulan kodun en kolay kısmı olan getItemCount() metoduyla başlayalım. Dizideki öğe sayısını, dizi boyutu özelliğini çağırarak nasıl alacağımızı biliyoruz.

class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

        }

        override fun getItemCount(): Int {
         return fruitArray.size
        }

        override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

        }
    }

Ardından onCreateViewHolder yöntemini uygulayacağız. Bu aşamada RecyclerView bizden bir FruitViewHolder oluşturmamıza yardımcı olmamızı istiyor. Hatırlarsanız, FruitViewHolder sınıfımız şöyle görünüyordu:

class FruitViewHolder(fruitView: View): RecyclerView.ViewHolder(fruitView)

Bu işlem, XML dosyası olarak oluşturduğumuz fruitView'e (meyve görünümü) ihtiyaç duyar. Bu XML dosyasına bir referans oluşturabilir ve aşağıdaki gibi bir Görünüme dönüştürebiliriz.

class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

            var fruitView = LayoutInflater.from(parent.context).inflate(R.layout.one_fruit_view, parent, false)

            var fruitViewHolder = FruitViewHolder(fruitView)

            return fruitViewHolder

        }

        override fun getItemCount(): Int {
            return fruitArray.size
        }

        override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

        }
    }

Geriye kalan kısım ise onBindViewHolder geçersiz kılma işlemidir.

fun onBindViewHolder(holder: FruitViewHolder, position: Int)

RecyclerView.Adapter, listemizden bir öğe almak için kullandığımız bir pozisyon tamsayı değeri ister. Ayrıca, fruitArray'den aldığımız öğeyi, ViewHolder içinde tutulan View'e bağlayabilmemiz için bir tutucu da sağlar. ViewHolder içinde tutulan View'e ViewHolder.itemView alanı üzerinden erişilebilir. View'i aldıktan sonra, daha önce oluşturduğumuz fruitName kimliğini kullanarak içeriği ayarlayabiliriz.

override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

          var ourFruitTextView = holder.itemView.findViewById<TextView>(R.id.fruitName)

          var aFruitName = fruitArray.get(position)

          ourFruitTextView.setText(aFruitName)
      }

Böylece FruitArrayAdapter'ımız tamamlanmış oluyor ve aşağıdaki gibi görünüyor.

class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

            var fruitView = LayoutInflater.from(parent.context).inflate(R.layout.one_fruit_view, parent, false)

            var fruitViewHolder = FruitViewHolder(fruitView)

            return fruitViewHolder
        }

        override fun getItemCount(): Int {
            return fruitArray.size
        }

        override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

            var ourFruitTextView = holder.itemView.findViewById<TextView>(R.id.fruitName)

            var aFruitName = fruitArray.get(position)

            ourFruitTextView.setText(aFruitName)
        }
    }

Son olarak, RecyclerView'ımızın geri kalan parçalarını birbirine bağlamaya hazırız. Bu parçalar, RecyclerView'a listenin içeriğini nasıl görüntüleyeceğini, LinearLayoutManager kullanarak doğrusal bir şekilde mi yoksa GridLayoutManager veya StaggeredGridLayoutManager kullanarak bir ızgara şeklinde mi göstereceğini söyleyecek bir LayoutManager oluşturuyor.

Düzen Yöneticisi Oluştur

onCreate fonksiyonumuzun içine geri döneceğiz ve LayoutManager'ı ekleyeceğiz.

override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)

       var fruitLinearLayout = LinearLayoutManager(this)

       myFruitRecyclerView.layoutManager =fruitLinearLayout

   }

Adaptörümüzü öğelere bağlayın ve RecyclerView'a ayarlayın

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)

        var fruitLinearLayout = LinearLayoutManager(this)

        myFruitRecyclerView.layoutManager =fruitLinearLayout

        var fruitListAdapter = FruitListAdapter(fruitNames)

        myFruitRecyclerView.adapter =fruitListAdapter
    }

Ayrıca bir fruitListAdapter örneği oluşturduk ve ona meyve isimlerinin dizisini verdik. Ve temel olarak, işimiz bitti. MainActivity.kt dosyasının tamamı aşağıdaki gibidir.

package com.guru99.learnrecycler

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {

    var fruitNames:Array<String> = arrayOf<String>("Banana", "Mango", "Passion fruit", "Orange", "Grape")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)

        var fruitLinearLayout = LinearLayoutManager(this)

        myFruitRecyclerView.layoutManager =fruitLinearLayout

        var fruitListAdapter = FruitListAdapter(fruitNames)

        myFruitRecyclerView.adapter =fruitListAdapter
    }

    class FruitViewHolder(fruitView: View): RecyclerView.ViewHolder(fruitView)

    class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

            var fruitView = LayoutInflater.from(parent.context).inflate(R.layout.one_fruit_view, parent, false)

            var fruitViewHolder = FruitViewHolder(fruitView)

            return fruitViewHolder
        }

        override fun getItemCount(): Int {
            return fruitArray.size
        }

        override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

            var ourFruitTextView = holder.itemView.findViewById<TextView>(R.id.fruitName)

            var aFruitName = fruitArray.get(position)

            ourFruitTextView.setText(aFruitName)
        }
    }
}

Projeyi İndir

SSS

RecyclerView, ListView'in daha esnek ve verimli halefidir. ViewHolder desenini uygular, düzen yöneticileri aracılığıyla doğrusal, ızgara ve kademeli düzenleri destekler ve yerleşik öğe animasyonları eklerken, ListView varsayılan olarak bunların hiçbirini sunmaz.

GridView yalnızca öğeleri sabit bir ızgarada görüntüler. RecyclerView, GridLayoutManager kullanarak bir ızgara oluşturabilir, ancak aynı zamanda doğrusal ve kademeli düzenleri, görünüm geri dönüşümünü ve animasyonları da destekleyerek GridView'den çok daha çok yönlüdür.

Bu RecyclerView örneği, resmi olarak önerilen dil olan Kotlin ile yazılmıştır. Google için Android geliştirme ortamında da aynı RecyclerView, adaptör ve düzen yöneticisi API'leri çalışır. Java.

ViewHolder veya onBindViewHolder içinde bir tıklama dinleyicisi ekleyin, ardından bunu bir arayüz geri çağırma işlevi aracılığıyla etkinliğe veya parçaya sunun. ViewHolder konumunu kullanmak, tıklamaların yanlış geri dönüştürülmüş öğeye bağlanmasını önler.

DiffUtil, iki liste arasındaki farkı hesaplayan ve adaptöre minimum güncelleme kümesini gönderen bir yardımcı sınıftır. Dinamik liste değişikliklerini verimli hale getirir ve eklemeleri, çıkarmaları ve taşımaları otomatik olarak canlandırır.

Jetpack Compose, yeni ekranlar için RecyclerView yerine LazyColumn ve LazyRow kullanır. Bununla birlikte, RecyclerView mevcut View tabanlı projelerde yaygın olarak kullanılmaya devam etmektedir ve birlikte çalışabilirlik API'leri aracılığıyla Compose'un içine yerleştirilebilir.

Evet. GitHub Copilot ve GPT tabanlı araçlar gibi yapay zeka asistanları, kısa bir komut istemiyle RecyclerView adaptörü, ViewHolder ve onBindViewHolder şablonu oluşturabilir. Geliştiricilerin yine de oluşturulan kodu doğruluk ve performans açısından incelemesi gerekir.

Makine öğrenme Android Uygulamalar, öneriler, arama sıralamaları veya görüntü sınıflandırmaları gibi dinamik çıktıları oluşturmak için RecyclerView kullanır. Adaptör, model sonuçlarını liste öğelerine bağlayarak büyük ve sık değişen veri kümelerinin sorunsuz bir şekilde kaydırılmasını sağlar.

Bu yazıyı şu şekilde özetleyin: