Android Kaydırdıkça Yükleme – Load More Data (Kotlin)

Merhaba sevgili android geliştiricileri. Bu yazıda sizlere Android load more data’yı anlatacağım. Load more data yani kaydırdıkça daha fazla yükleme (Endless Scrolling) özelliği kullanıcı ve telefon açısından oldukça önemlidir.

Ram kullanımı ve internet kullanımı gibi birçok konuda önemli bir noktalara direkt olarak olumlu etki eder. Android Paging, Pagination, Endless Scrolling ve RecyclerView olarak da anılan bu özelliği gelin hep birlikte tanıyalım…

Android RecyclerView Nedir?

Android RecyclerView, içeriklerin sayfa yüklendikçe yüklenmesini sağlayan bir Android geliştirme özelliğidir. Android paging, pagination ve endless scrolling olarak da adlandırılmaktadır.

Paging - Pagination RecyclerView Endless ScrollingAndroid Endless Scrolling Neden Gereklidir?

Bir sosyal medya uygulaması düşünelim örneğin Facebook. Facebook tüm arkadaşlarınızın paylaşımlarını, haberleri, reklamları ve hikayeleri aynı anda size sunarsa kaç saniyede yüklenirdi? Bence 1 ile 5 dakika sürerdi bu.

Sadece sizin internetinizin hızı önemli değil sunucu hızı ve cevap süresi aynı zamanda önemli. Tabi herkes tüm verileri aynı anda isterse işler karışır Mark amca dükkanı kapatır 🙂 Bunun yerine istenilen verileri, listeyi sınırlı sayıda paket olarak vermek daha mantıklıdır.

Android Pagination Nasıl kullanılır?

Her kafadan bir ses çıkabileceği gibi benimde bu konuda herkesten farklı bir fikrim var. Daha doğrusu birçok kullanımdan farklı bir yol. Listeyi 20’li parçalara bölmek ve listenin en altına gelindiğinde sıradaki 20’li parçayı almak.

Paging - Pagination RecyclerView Endless ScrollingÖnce RecyclerView kütüphanesi ve tasarımlar..

  • Öncelikle android studio açalım.
  • Yeni bir proje oluşturalım. Elbette kotlin dilinde 🙂
  • <app>/build.gradle içerisini şu şekilde değiştirelim ve ‘sync now’ tuşu ile senkronize edelim.
    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'
        implementation 'androidx.recyclerview:recyclerview:1.1.0'
    }
  • Şimdi sırası ile özelleştirilmiş liste elemanlarımızı ekleyelim. Önce normal liste elemanınız. Bu yükleme durumunun haricinde normal verilerimizi göstereceğimiz liste.(list_item_text_row.xml)
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:orientation="horizontal">
    
        <ImageView
            android:layout_width="?actionBarSize"
            android:layout_height="match_parent"
            android:layout_margin="5dp"
            android:src="@mipmap/ic_launcher"/>
    
        <TextView
            android:id="@+id/list_item_text_row_textTitle"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="@string/app_name"
            android:gravity="center|start"
            android:textStyle="bold"
            android:textSize="20sp"/>
    
    </LinearLayout>
  • Şimdi yükleme durumunu göstereceğimiz liste tasarımını ekleyelim. (list_item_loading_row.xm)
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize">
    
        <ProgressBar
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    </LinearLayout>
  • Liste tasarımlarımız bittiğine göre MainActivity tasarımını yapalım. Bu ekranda sadece RecyclerView olacak. (activity_main.xml)
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        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="match_parent"
        tools:context=".MainActivity">
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/activity_main_recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </LinearLayout>
  • Tasarım kısmını bitirdik.

Şimdi biraz zahmetli kısımdayız

  • Öncelikle listemizde eleman olarak model ekleceğiz. O yüzden örnek model sınıfını oluşturalım. (Model.kt)
    class Model(val position: Int)
  • Şimdi sırası ile liste elemanlarını tanımlacağımız holder’ları yazalım. Önce loading holder. (HolderLoading.kt)
    import android.view.View
    import androidx.recyclerview.widget.RecyclerView
    
    class HolderLoading(view: View): RecyclerView.ViewHolder(view)
  • Burada progressBar var. Fakat tanımlamaya gerek yok. Bu yüzden burası sade. Şimdi sırada normal item’ların olduğu sınıf. (HolderModel.kt)
    import android.view.View
    import android.widget.TextView
    import androidx.recyclerview.widget.RecyclerView
    
    class HolderModel(view: View): RecyclerView.ViewHolder(view){
        val textTitle: TextView = view.findViewById(R.id.list_item_text_row_textTitle)
    }
  • Burada TextView görünümünü tanımladık. Listeleme sırasında pozisyon bilgisini yazdıracağız. Şimdi sıra adaptörümüzde. (Adapter.kt)
    class Adapter(private val arrayList: ArrayList<Model?>): RecyclerView.Adapter<RecyclerView.ViewHolder>(){
    
        private val VIEW_TYPE_ITEM = 0 //Normal item
        private val VIEW_TYPE_LOADING = 1 //Yükleniyor
    
        override fun getItemViewType(position: Int): Int {
            if (arrayList[position] == null){ //Eğer model boş ise (arrayList.add(null) ile kullandık) yükleniyor
                return VIEW_TYPE_LOADING
            } else { //Değilse normal item
                return VIEW_TYPE_ITEM
            }
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
            if (viewType == VIEW_TYPE_ITEM){ //view type değerine göre görüntü layout'u ekliyoruz
                return HolderModel(LayoutInflater.from(parent.context).inflate(R.layout.list_item_text_row, parent, false))
            } else {
                return HolderLoading(LayoutInflater.from(parent.context).inflate(R.layout.list_item_loading_row, parent, false))
            }
        }
    
        override fun getItemCount(): Int {
            return arrayList.size
        }
    
        override fun onBindViewHolder(recyclerHolder: RecyclerView.ViewHolder, position: Int) {
            val model: Model? = arrayList[position]
    
            if (recyclerHolder is HolderLoading){ //Yükleniyor
                var holder: HolderLoading = recyclerHolder
                //Yükleniyor kısmı. progress bar burada
            } else if (recyclerHolder is HolderModel){ //Normal item
                var holder: HolderModel = recyclerHolder
                //burada işlem olarak text içeriğini değiştiriyoruz
                holder.textTitle.text = "Position : ${model?.position}"
            }
        }
    }
  • Son olarak MainActivity.kt
    class MainActivity : AppCompatActivity() {
    
        private val loadTime: Long = 1000 * 2L //yüklenme süresini 2 saniye olarak aldık
        private var isLoading: Boolean = false //Yüklenme işleminin başlamasını ve bitmesini kontrol eden bool değişkeni
        private var itemPosition: Int = 0 //pozisyon bilgisi
    
        private val arrayList: ArrayList<Model?> = ArrayList()
        private lateinit var layoutManager: LinearLayoutManager
        private lateinit var adapter: Adapter
        private lateinit var recyclerView: RecyclerView
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            layoutManager = LinearLayoutManager(this@MainActivity)
    
            adapter = Adapter(arrayList)
            recyclerView = findViewById(R.id.activity_main_recyclerView)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
    
            recyclerView.addOnScrollListener(object: RecyclerView.OnScrollListener(){
                override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                    super.onScrolled(recyclerView, dx, dy)
                    var lastPosition: Int = layoutManager.findLastVisibleItemPosition() //Görünen son görünümün pozisyonunu alır
                    var listSize: Int = arrayList.size //liste uzunluğu
    
                    if (!isLoading && listSize == (lastPosition + 1)) { //eğer yüklenme işlemi yoksa ve liste en aşağıdaysa
                        addLoadMoreData() //yeni değerleri yükle
                        isLoading = true //yükleniypr
                    }
                }
            })
            addItems()
        }
    
        private fun addLoadMoreData(){
            arrayList.add(null) //listeye boş bir görüntü model ekle. Bunu adapterda eğer boş ise yükleniyor anlamında kullanacağız
            adapter.notifyItemInserted(arrayList.size - 1) //adapter son itemi alıyor
            layoutManager.scrollToPosition(arrayList.size - 1) //listeyi kaydırıyoruz
    
            Handler().postDelayed({ //2 saniye sonra
                arrayList.removeAt(arrayList.size - 1) //yükleniyor progressBar item'ini siliyoruz
                adapter.notifyItemRemoved(arrayList.size) //son değerin silindiğini adaptera bildiriyoruz
                isLoading = false //Yüklenmiyor
                addItems() //yeni itemleri gönderiyoruz
            }, loadTime)
        }
    
        private fun addItems(){
            var i: Int = 0
            while (i < 20) {
                arrayList.add(Model(++itemPosition)) //itemleri ekliyor
                i++
            }
            adapter.notifyDataSetChanged() //listeyi yeniliyor
        }
    }
  • Şimdi uygulamayı test edelim.
Android Load More Data
Android Load More Data
Android Load More Data
Android Load More Data

 

 

 

 

 

 

 

 

Bu yazıda android load more data konusuna yer verdik. Proje kodlarına buradan ulaşabilirsiniz. Android Paging, Pagination, Endless Scrolling ve RecyclerView hakkında Soru, görüş ve önerileriniz için lütfen yorum yapmayı unutmayın.

Photo of author

Mehmet Kurtgöz

Android Developer.

Yorum yapın