Bu videoda temel olarak nasıl Custom ArrayAdapter yazabiliriz konusuna bakacağız. Bir ListView'im var. Aynı zamanda bir layout üzerinde bi tasarım oluşturdum. Bu tasarımdaki verileri ListView'in içerisine Adapter aracılığı ile eklemeye çalışacağız.
activity_main.xml kodları
<?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"
tools:context=".MainActivity">
<ListView
android:id="@+id/ulkelerListesi"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
tek_satir_ulke.xml kodları
<?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="wrap_content">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:text="Bilgi Al"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/ulkeAdi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="16dp"
android:text="Ulke adı"
app:layout_constraintStart_toEndOf="@+id/space"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/ulkeAciklamasi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="16dp"
android:text="Ülke Açıklaması"
app:layout_constraintStart_toEndOf="@+id/space"
app:layout_constraintTop_toBottomOf="@+id/ulkeAdi" />
<Space
android:id="@+id/space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="120dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java kodları
package com.example.customarrayadaptor;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
private ListView ulkelerListesi;
String[] ulkeler, ulkeTanimari;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ulkelerListesi = findViewById(R.id.ulkelerListesi);
Resources veriKaynagi = getResources();
ulkeler = veriKaynagi.getStringArray(R.array.Ulkeler);
ulkeTanimari = veriKaynagi.getStringArray(R.array.UlkelerAciklama);
BenimAdapter adapter = new BenimAdapter(this, ulkeler, ulkeTanimari);
ulkelerListesi.setAdapter(adapter);
}
}
Şimdi buradaki kodları incelemeye başlayalım. İlk kısımları geçiyorum bizim için öneli olan kısım aşağıdaki kısımdır.
BenimAdapter adapter = new BenimAdapter(this, ulkeler, ulkeTanimari);
ulkelerListesi.setAdapter(adapter);
Burada özel bir class tanımlamışız. Şimdi bu class'ın içine bakalım. Aynı zamanda setAdapter metodu AdapterView class'ının abstract bir metodudur. Aynı zamanda bu class ListView'in üst class'larındandır.
package com.example.customarrayadaptor;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.w3c.dom.Text;
public class BenimAdapter extends ArrayAdapter {
Context context;
String[] ulkeAdlari;
String[] ulkeAciklamalari;
public BenimAdapter(Context context, String[] ulkeAdlari, String[] ulkeAciklamalari)
{
super(context, R.layout.tek_satir_ulke, R.id.ulkeAdi, ulkeAdlari);
this.ulkeAdlari = ulkeAdlari;
this.ulkeAciklamalari = ulkeAciklamalari;
this.context = context;
Log.i("test","tes");
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View tekSatir = convertView;
ViewTutucu tutucu = null;
if(tekSatir == null)
{
LayoutInflater layoutInflater = LayoutInflater.from(this.context);
tekSatir = layoutInflater.inflate(R.layout.tek_satir_ulke, null);
tutucu = new ViewTutucu(tekSatir);
tekSatir.setTag(tutucu);
}
else
{
tutucu = (ViewTutucu) tekSatir.getTag();
}
tutucu.ulke.setText(this.ulkeAdlari[position]);
tutucu.tanim.setText(this.ulkeAciklamalari[position]);
return tekSatir;
}
}
class ViewTutucu
{
TextView ulke,tanim;
public ViewTutucu(View v)
{
ulke = v.findViewById(R.id.ulkeAdi);
tanim = v.findViewById(R.id.ulkeAciklamasi);
}
}
Burası karışık gelebilir. Sırasıyla üsünde duralım.
Bir class'ımız var ArrayAdapter class'ından miras alınmış. Yapıcı metodumuz aşağıda göüldüğü gibi.
public BenimAdapter(Context context, String[] ulkeAdlari, String[] ulkeAciklamalari)
{
super(context, R.layout.tek_satir_ulke, R.id.ulkeAdi, ulkeAdlari);
this.ulkeAdlari = ulkeAdlari;
this.ulkeAciklamalari = ulkeAciklamalari;
this.context = context;
Log.i("test","tes");
}
Örnekleme yapılırken alınan parametreleri burada görebiliyoruz. Bu sayede aslında strings.xml dosyası altındaki verileri class'ımıza taşımış olduk.
strings.xml
<resources>
<string name="app_name">CustomArrayAdaptor</string>
<string-array name="Ulkeler">
<item>Türkiye</item>
<item>Kıbrıs</item>
<item>Bulgaristan</item>
<item>Yunanistan</item>
</string-array>
<string-array name="UlkelerAciklama">
<item>Türkiye ülkesidir.</item>
<item>Kıbrıs ülkesidir.</item>
<item>Bulgaristan ülkesidir.</item>
<item>Yunanistan ülkesidir.</item>
</string-array>
</resources>
ArrayAdapter class'ındaki getView metodunu Override ederek işlemlerimize devam edeceğiz. Bu metot super(context, R.layout.tek_satir_ulke, R.id.ulkeAdi, ulkeAdlari); metodundaki ulkeAdlari değişkeni kadar çalışmaktadır. Bu sayede position bilgisiyle sürekli olarak yeni değerler ekrana yazılmaktadır.
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View tekSatir = convertView;
ViewTutucu tutucu = null;
if(tekSatir == null)
{
LayoutInflater layoutInflater = LayoutInflater.from(this.context);
tekSatir = layoutInflater.inflate(R.layout.tek_satir_ulke, null);
tutucu = new ViewTutucu(tekSatir);
tekSatir.setTag(tutucu);
}
else
{
tutucu = (ViewTutucu) tekSatir.getTag();
}
tutucu.ulke.setText(this.ulkeAdlari[position]);
tutucu.tanim.setText(this.ulkeAciklamalari[position]);
return tekSatir;
}
Sözde kod mantığı ile anlatmayı deneyeceğim. convertView dediğimiz yapı aslında garbage collector aracılığı ile kullanılmayan verileri silmemizi engelliyor. Yanlış duymadınız 🙂 Burada aslında süerekli oalrak CPU'yu yormaktayız çünkü inflater aracılığı ile XML'den bir View objesi oluşturmaya çalışıyoruz.. İlk başta convertView değeri null olacaktır. Eğer null'sa if bloğunun içine girerek tek_satir_ulke.xml dosyasından bir View oluşturmayı deneyecek ve bunu activity_main.xml içindeki ListView'e gönderecek. Bu esnada ViewTutucu isimli bir class karşımıza çıkıyor.
class ViewTutucu
{
TextView ulke,tanim;
public ViewTutucu(View v)
{
ulke = v.findViewById(R.id.ulkeAdi);
tanim = v.findViewById(R.id.ulkeAciklamasi);
}
}
Aslında bu class tek_satir_ulke.xml dosyası içeriesindeki TextView'lere erişmemizi ve içini doldurmamızı sağlayacaktır. Her seferinde tekrar tekrar erişmeye çalışmak performans kaybı olacağı için ayrı bir class'ta yazılmıştır.
Daha sonrasında setTag ve getTag'ler yardımı ile position bilgisine göre ifadeler doldurulur.
tutucu.ulke.setText(this.ulkeAdlari[position]);
tutucu.tanim.setText(this.ulkeAciklamalari[position]);
return tekSatir;
İlk Yorumu Siz Yapın