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.
Konu Başlıkları
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.
Android 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.
Ö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.
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.