RecyclerView ile Liste Oluşturmak (Kotlin)

UYARI: Bu yazıdan önce aşağıdaki yazıları okumanız ve bilgisayarınıza Android Studio uygulamasını yüklemeniz gerekiyor. Eğer ilk defa Android uygulaması geliştirmeye başlayan biriyseniz aşağıdaki üç makaleyi sırayla uygulamanız kesinlikle tavsiye edilir.

1. Android Studio Kurulumu
2. İlk Android Projemizi Oluşturmak
3. İlk Android Projeyi Çalıştırmak

RecyclerView, ListView kontrolünden daha esnek ve daha gelişmiş bir widget’tir. Daha büyük veri kümelerini görüntülemek için tasarlanmıştır. Bu widget ağ ile ilgili eylemlerde özellikle kullanılır.

Çalışma mekanizması aşağıdaki grafikte gösterilmiştir.

Bu widget ile çalışırken, Adapter ve LayoutManager oluşturmalıyız. Adapter oluşturmak için RecyclerView.Adapter sınıfı kullanılır.

LayoutManager, elemanların nasıl listeleneceğini belirlemek için kullanılır (yatay veya dikey olarak). Grafiği incelerseniz, adapter nesnesinin verileri aldığını, LayoutManager nesnesinin ise RecyclerView içerisinde bulunduğu görürsünüz. Gelen verilerin nasıl sıralanacağı tamamen LayoutManager nesnesine bağlıdır.

Liste içerisinde her bir eleman aşağıdaki nesneler yardımıyla sıralanır.

  • LinearLayoutManager 
  • GridLayoutManager 

LinearLayoutManager sınıfı, listedeki elemanları yatay veya dikey olarak listeler. GridLayoutManager sınıfı ise, listedeki her bir elemanı ızgarada göstermeye yarar.

Bir diğer önemli gelişme ise, RecyclerView’da, ViewHolder kullanımı zorunlu kılınmıştır. Bu işlem için özel bir sınıf geliştirilmiştir.

CardView, FrameLayout sınıfından extend edilen bir yapıdır. RecyclerView ile oluşturulan listelerin daha tutarlı olmasını sağlar. Bu yapılara gölge(shadow) verilebilir ve kenar köşeleri(corners) yuvarlatılabilir. Fakat bu iki özellik API 21 ve üstü sürümlerde etkisini gösterir.

Bu bilgilerden sonra RecyclerView kullanarak Kotlin dili yardımıyla bir liste oluşturabiliriz. Öncelikle uygulamanızın aşağıdaki yoluna sahip olan dosyasını açalım.

Aşağıda verilen iki satırı kopyalayıp dependencies bloğuna yapıştırınız.

implementation ‘com.android.support:recyclerview-v7:28.0.0’
implementation ‘androidx.cardview:cardview:1.0.0’

Bunu yaptıktan sonra projeyi Build -> Rebuild ile yeniden oluşturunuz. Bu işlemden sonra kütüphaneler uygulamaya eklenir.

Uygulama arayüzü için öncelikle aşağıda verilen kodları activity_main isimli xml dosyasına ekleyiniz.

<?xml version="1.0" encoding="utf-8"?>
<!--RecyclerView kontrolümüzü ekleyelim. -->
<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/my_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />

RecyclerView içerisinde veriler satır satır gösterilir. Her bir satır için ortak bir arayüz tasarımı yapalım. Bunun için custom_layout isimli yeni bir xml oluşturduk. Kodları aşağıdaki gibidir.

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

    <!--CardView kontrolümüzü ekledik.
    card_view:cardBackgroundColor: Arka plan rengini belirler.
    card_view:cardCornerRadius: Köşeleri yuvarlatır.
    card_view:cardElevation: Gölge vermek için kullanılır (API 21
    ve üstü sürümlerde daha iyi çalışır)-->
    <androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:padding="5dp"
        card_view:cardBackgroundColor="#fff"
        card_view:cardCornerRadius="10dp"
        card_view:cardElevation="5dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/img"
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:layout_gravity="center_vertical"
                android:layout_margin="8dp"
                android:scaleType="centerCrop"
                android:src="@drawable/kotlin" />

            <TextView
                android:id="@+id/lang"
                android:layout_width="132dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:maxLines="3"
                android:text="Kotlin"
                android:textColor="#222"
                android:textSize="25sp" />
        </LinearLayout>
    </androidx.cardview.widget.CardView>
</RelativeLayout>

Arayüz tasarımını tamamladıktan sonra RecyclerView kontrolünü doldurmak için adapter sınıfı oluşturmamız gerekiyor. Oluşturduğumuz MyAdapter.kt sınıfı ve kodların açıklaması aşağıdaki gibidir.

package com.mas.recyclerviewapp

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
/*RecyclerView.Adapter: Adapter oluşturmak için bu sınıf kullanılır.
Adapter sınıfları, veri ile AdapterView arasındaki bağlantıyı sağlar.*/
/*Kurucu metot ile ihtiyaç duyulan parametreler alınır.
Burada iki adet Array ile çalıştık. Biri resimleri diğeri de
programlama dili isimlerini tutmayı sağlar.*/
class MyAdapter(
    private val images_lang: ArrayList<Int>,
    private val languages: Array<String>,
    val applicationContext: Context
) :
    RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
    /*RecyclerView ve ListView içerisinde periyodik
    olarak findViewById metodunu çağırmak performansı düşürebilir.
    Bundan dolayı bu işlem için ViewHolder sınıfı kullanılır.*/
    class MyViewHolder(val layout: RelativeLayout) : RecyclerView.ViewHolder(layout) {
        val img = layout.findViewById<ImageView>(R.id.img)
        val lang = layout.findViewById<TextView>(R.id.lang)
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter.MyViewHolder {
        /*Her bir satır temsil edecek arayüz seçilir.*/
        val relativeLayout = LayoutInflater.from(parent.context).inflate(
            R.layout.custom_layout,
            parent,
            false
        ) as RelativeLayout

        return MyViewHolder(relativeLayout)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        /*Her bir görünümün içeriği belirlenir.*/
        holder.lang.text = languages[position]
        holder.img.setImageResource(images_lang[position])
        holder.layout.setOnClickListener {
            Toast.makeText(
                applicationContext,
                languages[position],
                Toast.LENGTH_SHORT
            ).show()
        }
    }

    /*Gelen verilerin boyutu*/
    override fun getItemCount() = languages.size
}

Adapter yapısı ve kodları yukarıdaki gibidir. Bu sınıf arayüz ile verilerin bir araya gelmesini sağlar. Arayüzleri daha önce tasarladık şimdi de kullanacağımız verileri oluşturmamız gerekiyor. İlk verimiz strings.xml dosyasında bulunan string-array etiketindeki bulunan verilerdir.

<resources>
    <string name="app_name">RecyclerViewApp</string>
    <string-array name="programming">
        <item>Java</item>
        <item>Kotlin</item>
        <item>C++</item>
        <item>C</item>
        <item>F#</item>
    </string-array>
</resources>

Yukarıda verilen verileri satır satır RecyclerView içinde göstereceğiz. Ayrıca her dilin logosunu da yanında göstermek istiyoruz. Kullandığımız resimleri drawable klasöründe aşağıdaki gibi ekliyoruz.

MyAdapter.kt sınıfı son haliyle herhangi bir işe yaramaz. Bunu uygulamanın ana giriş noktası olan MainActivity.kt isimli dosyada kullanmamız gerekiyor. Bu sınıfın kodları şöyledir:

package com.mas.recyclerviewapp

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


class MainActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView
    private lateinit var viewAdapter: RecyclerView.Adapter<*>
    private lateinit var viewManager: RecyclerView.LayoutManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        /*Veriler alınır. Bunun için drawable klasöründe bulunan
        resimlerin ID bilgisi ArrayList yapısına eklenir.*/
        val images_lang = ArrayList<Int>()
        images_lang.add(R.drawable.java)
        images_lang.add(R.drawable.kotlin)
        images_lang.add(R.drawable.cplus)
        images_lang.add(R.drawable.c)
        images_lang.add(R.drawable.fsharp)

        /*strings.xml dosyasında tanımladığımız
        string array verileri alınır.*/
        val languages = resources.getStringArray(R.array.programming)

        viewManager = LinearLayoutManager(this)
        viewAdapter = MyAdapter(images_lang,languages, applicationContext)

        /*setHasFixedSize(true):Bu özelliği set ettiğimizde
        performansı arttırır. Eğer içeriğin değişmesi, RecyclerView
        düzen boyutunu değiştirmiyorsa bu özelliği set edebilirsiniz.

        layoutManager: Her bir satırın nasıl hizalanacağı belirlenir.
        Her satır dikey olarak hizalanır.

        adapter: RecyclerView, adapter ile doldurulur.*/
        recyclerView = findViewById<RecyclerView>(R.id.my_recycler_view).apply {
            setHasFixedSize(true)
            layoutManager = viewManager
            adapter = viewAdapter

        }

    }
}


Uygulama ile ilgili yapılması gereken tüm işlemler bunlardan ibarettir. Bu projede üzerinde çalıştığımız tüm dosyalar aşağıdaki gibidir.

Uygulamayı yükledikten sonra ekran çıktısı aşağıdaki gibi olur.

Kaynak kodu için tıklayınız.

**Bana en büyük desteğiniz yazılarıma yorum yapmanız ve paylaşmanızdır.