Android Uygulamasında Iterator Pattern ve Data Class Kullanımı (Galeri)

Merhaba değerli dostlar, daha önce Kotlin programlama dilinde Iterator Pattern ile ilgili iki farklı uygulama hazırlamıştım. Uygulamalar ve kaynak kodları hakkında ayrıntılı bilgiye ulaşmak için şu iki makalemi okumanızı öneriyorum. Çünkü bu başlık altında anlatacaklarım bu iki makaleyle doğrudan ilgilidir.

Kotlin’de Iterator Pattern
Kotlin’de Iterator Pattern ve Data Class Kullanım

Bu sayfaları incelediğinize göre yeni uygulamadan kısaca bahsetmek istiyorum. Uygulamanın amacı Kotlin ile bizlere sunulan Data Class yapısını ve Iterator Pattern tasarım kalıbını Android tabanlı bir uygulamada birleştirmektir. Bu yapıları kullanmadan klasik yöntemler ile veya kaba yöntemlerle bu uygulamayı yazabilirsiniz. Ancak bu zamana kadar birçok uygulama geliştirdim ve zaman içinde uygulamanın kodları artınca hataların tespiti zorlaşmaktadır. Ayrıca iş arayan bir mühendis veya öğrenciyseniz bu yöntemlerle hazırladığınız uygulamaları bir iş başvurusunda kullandığınız zaman programcılık ile ilgili temel kavramlardan habersiz olduğunuz izlenimi verebilirsiniz. Amacım; Kotlin ile Android Uygulamaları geliştirmeye yeni başlayan (veya kendini geliştirmek isteyen) arkadaşların doğru yöntemlerle ilerlemesine yardımcı olmaktır. Umarım amacıma ulaşır ve sizlere faydalı uygulamalar ve bilgilere ile yardımcı olabilirim.

Bu kısa bilgilendirme ile beraber Uygulamanın örnek ekran çıktısını sizlerle paylaşmak istiyorum. Böylece ne yapmak istediğimiz sizlere daha net bir şekilde aktarabilirim.

Uygulamanın Ekran Çıktısı

Uygulamanın amacı drawable klasöründe bulunan resimler arasında gezinmeyi ve resimlerle ilgili bilgiyi TextView bileşeninde göstermeyi sağlamaktır. Bu işlemi yapmak için sayfaya eklediğimiz Button bileşenlerini kullanacağız. Uygulama hakkında fikir sahibi olduğunuza göre şimdi yapacağımız işlemleri adım adım yazmak istiyorum.

  • Yeni bir Android projesi oluşturmak
  • Language isimli Data Class oluşturmak.
  • Iterator Pattern için ilgili interface ve class bileşenlerini oluşturmak.
  • Uygulamanın activity_main.xml arayüz dosyasını hazırlamak. Yani arayüzünü tasarlamak.
  • Uygulamanın MainActivity.kt sınıfı için ihtiyacımız olan kodları yazmak.

Yeni bir proje oluşturduktan sonra proje içinde ihtiyacımız olan iki adet klasör (iterator ve model) oluşturalım. Klasörlerin aşağıdaki gibi oluştuğuna dikkat edelim.

model klasörüne, oluşturacağımız Language Data Class’ını ekleyeceğiz. Uygulama geliştirirken bu şekilde paket veya klasörler oluşturarak uygulama kodlarınızı mutlaka sınıflandırınız. Böylece uygulama kodlarınızın daha düzenli durmasını sağlar ve kodu inceleyenlerin daha çabuk kavramasına yardımcı olursunuz.
İhtiyacımız olan Language.kt isimli Data Class aşağıdaki gibi olacak.


package com.mas.iteratorpattern.model

class Language(val img: Int,
               var name: String)

Şimdi, iterator klasöründe bulunan interface ve class bileşenlerini tek tek açıklayalım.

Iterator (Interface)

package com.mas.retrofitapp.iterator

import com.mas.iteratorpattern.model.Language

interface Iterator {
    fun hasNext(): Boolean
    fun next(): Language?
    fun hasPrev(): Boolean
    fun prev(): Language?
}

Container (interface)

package com.mas.retrofitapp.iterator

interface Container {
    fun getIterator(): Iterator
}

Bu iki bileşen kelimenin tam anlamıyla şu an için hiçbir işi yaramaz. Ancak uygulama içinde bizleri büyük bir sorundan kurtarıyor. Design Pattern yani tasarım kalıpları arayüz ile asıl işlemlerin yapıldığı kod parçaları arasında köprü görevi gören ve kodlarınızı inanılmaz kullanışlı kılan yöntemlerdir. Eğer JSON gibi veriler ile çalışan bir uygulama geliştiriyorsanız Iterator Pattern kesinlikle kullanmanız gereken bir tasarım kalıbıdır. Ben uygulamalarımda aktif bir şekilde ve sürekli olarak kullanıyorum. Bu iki arayüz bileşenini kullandığımız asıl sınıfımız aşağıdaki gibidir.

Images.kt

package com.mas.retrofitapp.iterator

import com.mas.iteratorpattern.R
import com.mas.iteratorpattern.model.Language

//Language modelini kullanan ArrayList tanımladık.
var languages = ArrayList<Language>()

class Images : Container {
    override fun getIterator(): Iterator {
        /*languages ArrayList'ine ilgili verileri aşağıdaki gibi ekledik.
        Kullandığımız Language modelinden dolayı ArrayList 
        yapısına Language nesneleri ekledik. Her bir nesne iki parametre 
        almaktadır.*/
        languages.add(Language(R.drawable.kotlin, "Kotlin"))
        languages.add(Language(R.drawable.java, "Java"))
        languages.add(Language(R.drawable.c, "C"))
        languages.add(Language(R.drawable.cplus, "C++"))
        languages.add(Language(R.drawable.fsharp, "F#"))
        return NameIterator()
    }

    class NameIterator : Iterator {
        var index: Int = -1

        override fun hasNext(): Boolean {
            if (index < languages!!.size) {
                return true
            }
            return false
        }

        override fun next(): Language? {
            if (this.hasNext()) {
                return languages!!.get(++index)
            }
            return null
        }

        override fun hasPrev(): Boolean {
            if (index > 0) {
                return true
            }
            return false
        }

        override fun prev(): Language? {

            if (this.hasPrev()) {
                return languages!!.get(--index)
            }

            return null
        }
    }
}

Bu sınıf için dikkat edilmesi kodlar şunlardır.

var languages = ArrayList() : ArrayList ile bir koleksiyon oluşturduk. Koleksiyon veri olarak Language nesnesi alır.

languages.add(Language(R.drawable.kotlin, “Kotlin”)): languages koleksiyonuna veri olarak Language nesnesi ekledik. Lanugage Data Class’ı parametre olarak iki değer almaktadır: Int ve String. İlk parametre, uygulamanın drawable klasöründe bulunan resmin ID bilgisini, diğeri ise resimle ilgili açıklamayı tutmaktadır.

Iterator Pattern ile ilgili yapılması gerekenler bu kadar. Images sınıfını MainActivity içinde birazdan kullanacağız. O halde uygulamanın arayüzü için ihtiyacımız olan kodları paylaşabiliriz.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:background="@android:color/white"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="80dp"
        android:text="Programming Languages"
        android:textSize="25sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="318dp"
        android:layout_height="349dp"
        android:padding="16dp"
        app:layout_constraintBottom_toTopOf="@+id/ibRight"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.516"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2"
        app:layout_constraintVertical_bias="0.13"
        app:srcCompat="@drawable/back" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Welcome"
        android:textSize="25sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/ibLeft"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView"
        app:layout_constraintVertical_bias="0.436" />

    <!--android:onClick="left"
     Bu öznitelik çok önemlidir. Bu butona tıklama yapılırsa
     MainActivity.kt sınıfında bulunan "left" isimli metot çalışır.-->
    <ImageButton
        android:id="@+id/ibLeft"
        android:layout_width="144dp"
        android:layout_height="91dp"
        android:layout_marginStart="48dp"
        android:layout_marginBottom="16dp"
        android:background="@android:color/white"
        android:onClick="left"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:srcCompat="@drawable/left" />

    <!--android:onClick="left"
     Bu öznitelik çok önemlidir. Bu butona tıklama yapılırsa
     MainActivity.kt sınıfında bulunan "right" isimli metot çalışır.-->
    <ImageButton
        android:id="@+id/ibRight"
        android:layout_width="144dp"
        android:layout_height="91dp"
        android:layout_marginBottom="16dp"
        android:background="@android:color/white"
        android:onClick="right"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.226"
        app:layout_constraintStart_toEndOf="@+id/ibLeft"
        app:srcCompat="@drawable/right" />

</androidx.constraintlayout.widget.ConstraintLayout>

Burada en önemli kısım ImageButton bileşenlerine eklenen android:onClick özelliğidir. Buraya MainActivity.kt sınıfında bulunan metotların isimi verilmelidir.
Uygulamanın arayüzü bu kodlar ile birlikte aşağıdaki gibi görünmelidir.

Çok az kaldı arkadaşlar. Biliyorum bu kadar şeyi okumak zor ama emin olun hazırlaması daha zor. Son olarak MainActivity.kt isimli sınıfımızın kodlarını yazabiliriz.

package com.mas.iteratorpattern

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.mas.iteratorpattern.model.Language
import com.mas.retrofitapp.iterator.Images

class MainActivity : AppCompatActivity() {

    //Images sınıfı ile bir iterator oluşturuyoruz.
    var iter = Images().getIterator()


    lateinit var imageView: ImageView
    lateinit var textView: TextView

    //Language sınıfından bir adet nesne 
    lateinit var lang: Language
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //Arayüz bileşenlerinden ImageView ve TextView'e erişim sağlarız
        imageView = findViewById<ImageView>(R.id.imageView)
        textView = findViewById<TextView>(R.id.textView)
    }

    /*ImageButton'ların onClick özelliğine verilen left ve right metotları*/
    fun right(v: View) {
        /*iter.hasNext() ile koleksiyonda veri olup olmadığı kontrol edilir
        Koleksiyonda sonraki verinin gösterimini sağlar.*/
        if (iter.hasNext()) {
            //Eğer veri varsa iter.next ile Language nesnesi alınır.
            lang = iter.next()!!
            /*Language Data Class'ının iki parametresi var: img ve name
            Bunları kullanarak arayüz bileşenlerine ilgili veriler yerleştirilir.*/
            imageView.setImageResource(lang.img)
            textView.text = "" + lang.name
        }
    }

    fun left(v: View) {
        /*iter.hasNext() ile koleksiyonda veri olup olmadığı kontrol edilir
        Koleksiyonda önceki verinin gösterimini sağlar.*/
        if (iter.hasPrev()) {
            lang = iter.prev()!!
            imageView.setImageResource(lang.img)
            textView.text = "" + lang.name
        }
    }
}

MainActivity.kt ile ile ilgili açıklamaları kod ile birlikte verdim. Uygulama bu haliyle tamamlanmıştır. Uygulamada kullandığım tüm dosyalar ve nesneler aşağıdaki görselde işaretlenmiştir.

Uygulamanın ekran çıktısı aşağıdaki gibidir.

Uygulamanın kaynak kodları için tıklayınız.