Aklımda Kalası Kelimeler

* давайте работать вместе
* Zarf ve Mazruf, Zerafet(xHoyratlık) ile aynı kökten(za-ra-fe) gelir
* Bedesten
* Suç subuta ermiştir - Suç sabit olmuştur

17 Temmuz 2011 Pazar

Veri olmayan List görünümünde ekrana "Veri bulunamadı" gibi mesaj ver

Resimi sonradan yükledim ama yazının sonuna geldiğinizde daha anlamlı olacaktır.


ListActivity sınıfından türemiş bir sınıfınız ile içinde verileri göstereceğiniz bir ekran oluşturmak isteyelim.
Kıymetli noktalardan biri: ListActivity sınıfının adından da anlaşılacağı gibi Activity sınıfından türemiş olduğunu görebilmek.
İkinci kıymetli nokta ise Activity sınıfının Context sınıfından türetilmiş olduğunu bilmek.
Üçüncü ve bunların birleşim kümesi ise; this kelimesini Context parametre alabilen metotlara gönderebilmenizin her ne kadar ilk bakışta ListActivity sınıfından türetilen nesneyi (çalışan ekranınızı) işaret etsede aslında ListActivity : Activity : Context sınıflarını işaret ettiğini bilmeniz.

Şimdi gelelim Liste görünümünü sağlayan aşağıdaki LAYOUT dosyası olan liste.xml dosyamıza.

Öncelikle bu tip dosyaların isimleri, büyük harf içermiyor olmalı(ilk zamanlar "bu ne hatası" diye epeyce bakmıştım console da çıkan res\layout\listeCem.xml: Invalid file name: must contain only [a-z0-9_.] hatasına).

Bu layout içinde LinearLayout > ListView , TextView xml etiketleri var. Bu etiketlerin andorid tarafından anlamlarını biliyorsunuz.
LinearLayout : Doğrusal olarak, bileşenleri içeren kapsayıcı bileşen (Dilerseniz içindeki bileşenleri yukarıdan aşağı doğru(orientation:vertical), dilerseniz soldan sağa (orientation:horizontal) sıralar)

ListView, TextView : View sınıfından türetildiklerini farketmişsinizdir. ListView, verilerimizi satır satır gösterecek bileşen. Bu bileşene ayrıca bir template_row.xml adında bir dosya ile her satırın nasıl görünmesi gerektiğini bildireceğiz. TextView ise veri kümemizde(dataset) hiç gösterilecek bir satır yoksa burada "Hacı hiç veri yokki göstereyim" gibi bir metin göstereceğiz.

liste.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<TextView
android:id="@+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Gösterilecek bir şey yok...!"/>
</LinearLayout>


template_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="match_parent">

<TextView
android:id="@+id/tvTagListTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/tvTagListTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

template_row.xml dosyamız liste şeklinde göstereceğimiz verilerin her bir satırının nasıl olması gerektiğini belirttiğimiz xml dosyası.
Bu dosyayı ArrayAdapter sınıfından türettiğimiz InformationTagsAdapter sınıfında kullanacağız.

ArrayAdapter : Sınıfının (somut -class- ya da özet -abstract- mi bilemedim) adından bir ARRAY (diziyi)'i bir şeye adapte(ADAPTER) edecek.

InformationTagsAdapter.java

// ArrayAdapter sınıfından türettiklerimi farklı bir pakette tutmak istediğim için aşağıdaki satırı ekledim.
package cem.examples.reminder.adapters;

import java.util.ArrayList;
import android.app.Activity;
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 cem.examples.reminder.Information;
import cem.examples.reminder.R;

public class InformationTagsAdapter extends ArrayAdapter<Information> {
Activity activityCtx;
ArrayList<Information> infos;

// Yapıcı metoduma Context tipinde parametre geçirmem gerekiyor.
// Böylece bu adapter sınıfının kullanıldığı Context'i ArrayAdapter sınıfının yapıcı metoduna geçirebileceğim
// Ayrıca veri kümemi de yapıcı metot ile geçiriyorum ki ArrayAdapter sınıfnın yapıcısına geçsin ve veri bağlama(data binding)
// işine başlansın.
// Eğer küme boşsa xml içindeki android:id="@+id/android:empty" özellikli (attribute) xml etiketi
// "Gösterilecek bir veri yok" mesajını göstersin.
public InformationTagsAdapter(Activity _context, ArrayList<Information> _infos) {
super(_context, R.layout.template_row, _infos);
activityCtx = _context;
infos = _infos;
}


// Bu metot ArrayAdapter sınıfından geliyor. Override olduğuna göre ArrayAdapter abstract sınıftır ve bu metot abstract olarak tanımlanmış.
// Bu metoda veri kümesindeki kaçıncı eleman bağlanıyorsa int position parametresi ile,
// View convertView ile de listeye eklenecek satır parametre olarak geçiriliyor.
@Override
public View getView(int position, View convertView, ViewGroup parent) {

// Oluşturulacak satır eğer null ise R.layout.template_row ile template_row.xml dosyasının bir örneği LayoutInflater
// tarafından oluşturulur ve içindeki bileşenler tek tek veri kümesindeki, position'ıncı verinin elemanları ile bağlanır.
View v = convertView;
if (convertView == null) {
LayoutInflater inf = (LayoutInflater) activityCtx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inf.inflate(R.layout.template_row, parent, false);
}

Information info = infos.get(position);
if (info != null) {

// tvTagListTitle ve tvTagListTag TextView bileşenleri R.layout.template_row diye R.java dosyasında
// değişken olarak oluşturulan ve template_row.xml dosyasını işaret eden dosyada bulunuyorlar.
TextView tvTitle = (TextView) v.findViewById(R.id.tvTagListTitle);
TextView tvTag = (TextView) v.findViewById(R.id.tvTagListTag);

if (tvTag != null && tvTitle != null) {
tvTitle.setText(info.MTitle);
for (String tag : info.MTags) {
tvTag.setText(tag);
}
}
}
return v;
}
}