Kapsamlı Anlatım ile Android RecyclerView Kullanımı

×

RecyclerView, Android'de liste veya grid gibi tekrarlayan verileri performanslı bir şekilde göstermek için kullanılan en güçlü bileşenlerden biridir. Modern Android uygulamalarında, eski ListView bileşeninin yerini tamamen almıştır. Bu makalede RecyclerView’un ne olduğunu, nasıl kullanıldığını ve en iyi kullanım pratiklerini adım adım öğreneceksiniz.


RecyclerView Nedir?

RecyclerView, Android Jetpack kütüphanelerinin bir parçasıdır ve büyük veri setlerinin verimli bir şekilde kullanıcıya sunulmasını sağlar. Adından da anlaşılacağı gibi, görünüm hücrelerini geri dönüştürerek (recycle) belleği ve işlemciyi optimize eder.

Özellikleri:

Gerekli Bağımlılıklar

build.gradle (app):

dependencies {
    implementation 'androidx.recyclerview:recyclerview:1.3.1'
}

Jetpack Compose kullanmıyorsanız RecyclerView için bu bağımlılık yeterlidir. Ek olarak ViewBinding aktif olmalıdır:

android {
    buildFeatures {
        viewBinding true
    }
}

RecyclerView Kullanım Adımları

RecyclerView kullanımı için temel bileşenler şunlardır:

  1. RecyclerView bileşeni (layout içinde)
  2. ViewHolder (her bir satırı temsil eden sınıf)
  3. Adapter (veriyi bağlayan sınıf)
  4. LayoutManager (liste düzeni)

1. XML Tasarımı

activity_main.xml

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:listitem="@layout/item_user" />

item_user.xml

<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:elevation="4dp"
    android:padding="12dp">

    <TextView
        android:id="@+id/textViewName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Kullanıcı Adı"
        android:textSize="18sp"
        android:textStyle="bold" />

</androidx.cardview.widget.CardView>

Model Sınıfı

data class User(val id: Int, val name: String)

ViewHolder ve Adapter

class UserAdapter(private val userList: List<User>) :
    RecyclerView.Adapter<UserAdapter.UserViewHolder>() {

    inner class UserViewHolder(val binding: ItemUserBinding) :
        RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        val binding = ItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return UserViewHolder(binding)
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val user = userList[position]
        holder.binding.textViewName.text = user.name
    }

    override fun getItemCount(): Int = userList.size
}

RecyclerView Tanımlama – MainActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val sampleList = listOf(
            User(1, "Ahmet Yılmaz"),
            User(2, "Zeynep Demir"),
            User(3, "Mehmet Kara")
        )

        val adapter = UserAdapter(sampleList)

        binding.recyclerView.layoutManager = LinearLayoutManager(this)
        binding.recyclerView.adapter = adapter
    }
}

ListAdapter ve DiffUtil ile Gelişmiş Kullanım (Önerilir)

RecyclerView içinde büyük veri setleriyle çalışırken notifyDataSetChanged() yerine DiffUtil kullanmak performansı ciddi oranda artırır.

class UserDiffCallback : DiffUtil.ItemCallback<User>() {
    override fun areItemsTheSame(oldItem: User, newItem: User) = oldItem.id == newItem.id
    override fun areContentsTheSame(oldItem: User, newItem: User) = oldItem == newItem
}

class UserListAdapter : ListAdapter<User, UserListAdapter.UserViewHolder>(UserDiffCallback()) {

    inner class UserViewHolder(val binding: ItemUserBinding) :
        RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        val binding = ItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return UserViewHolder(binding)
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val user = getItem(position)
        holder.binding.textViewName.text = user.name
    }
}

En İyi Kullanım Tavsiyeleri


RecyclerView ile Kullanılabilecek Diğer Olaylar ve Özellikler


1. Sonsuz Liste / Sayfalama (Pagination)

Büyük veri setlerinde verilerin hepsini aynı anda yüklemek hem kullanıcı deneyimini bozar hem de performans sorunlarına neden olur. Bunun yerine, verileri sayfa sayfa yüklemek (infinite scroll) tercih edilir.

Kullanım Mantığı:

recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        val layoutManager = recyclerView.layoutManager as LinearLayoutManager
        val lastVisibleItem = layoutManager.findLastVisibleItemPosition()
        val totalItemCount = layoutManager.itemCount

        if (!isLoading && lastVisibleItem >= totalItemCount - 3) {
            loadNextPage() // API'den sonraki verileri çek
            isLoading = true
        }
    }
})

2. Swipe ile Silme (Swipe to Delete)

RecyclerView’de bir öğeyi sağa veya sola kaydırarak silmek için ItemTouchHelper kullanılır.

val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder) = false

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        val position = viewHolder.adapterPosition
        myList.removeAt(position)
        adapter.notifyItemRemoved(position)
    }
}
ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView)

3. Drag & Drop

Öğelerin sürüklenerek yer değiştirmesini sağlamak için yine ItemTouchHelper kullanılabilir. Bu sayede kullanıcılar liste sırasını değiştirebilir.

4. Çoklu ViewType Kullanımı (Multiple View Types)

Bazı listelerde farklı tipte öğeler aynı RecyclerView içinde gösterilir. Örneğin, başlık, içerik ve footer gibi. Bunun için getItemViewType() metodu kullanılır.

override fun getItemViewType(position: Int): Int {
    return when (items[position]) {
        is Header -> VIEW_TYPE_HEADER
        is Content -> VIEW_TYPE_CONTENT
        is Footer -> VIEW_TYPE_FOOTER
        else -> throw IllegalArgumentException("Bilinmeyen tip")
    }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    return when (viewType) {
        VIEW_TYPE_HEADER -> {
            val binding = ItemHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            HeaderViewHolder(binding)
        }
        VIEW_TYPE_CONTENT -> {
            val binding = ItemContentBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            ContentViewHolder(binding)
        }
        VIEW_TYPE_FOOTER -> {
            val binding = ItemFooterBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            FooterViewHolder(binding)
        }
        else -> throw IllegalArgumentException("Bilinmeyen viewType")
    }
}

5. Item Seçimi & Vurgulama (Selection State)

RecyclerView öğelerinin seçilmesi ve seçili öğelerin vurgulanması için item'ların durumunu yönetmeniz gerekir. Basitçe adapter içinde seçili pozisyonu tutabilir ve seçimi değiştirdiğinizde ilgili itemların arayüzünü güncelleyebilirsiniz.

class UserAdapter(private val userList: List<User>) :
    RecyclerView.Adapter<UserAdapter.UserViewHolder>() {

    private var selectedPosition = RecyclerView.NO_POSITION

    inner class UserViewHolder(val binding: ItemUserBinding) :
        RecyclerView.ViewHolder(binding.root) {
        init {
            binding.root.setOnClickListener {
                notifyItemChanged(selectedPosition)
                selectedPosition = adapterPosition
                notifyItemChanged(selectedPosition)
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        val binding = ItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return UserViewHolder(binding)
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val user = userList[position]
        holder.binding.textViewName.text = user.name
        holder.itemView.isSelected = (selectedPosition == position)
        // Veya farklı bir vurgulama: background renk değiştirme gibi
        holder.itemView.setBackgroundColor(
            if (selectedPosition == position) Color.LTGRAY else Color.WHITE
        )
    }

    override fun getItemCount(): Int = userList.size
}

Eğer RecyclerView ile ilgili daha spesifik bir kullanım veya kod örneği istersen, ya da başka Android konularında destek lazım olursa bana sorabilirsin.

💬 Yorumlar
Henüz yorum yapılmamış. İlk yorumu sen yap! 👆