11 - Adapters, ListView,AdapterView
11.1 - Introduction to Adapters
Dummy
ListView-ArrayView-Serkan
Çay - https://www.youtube.com/watch?v=iSXxupDiteE
Custom
ListView - Serkan Çay : https://www.youtube.com/watch?v=yuTLTVczMko
Question/Answer
: : http://skillgun.com/android/adapters/interview-questions-and-answers
11.2 - What is the role of adapters in Android
http://stackoverflow.com/questions/3674951/whats-the-role-of-adapters-in-android
Well adapter in android are basically
bridge between UI components and the datasource that fill data into UI
Component. ( Adapter'ler, UI component'ler ve
datasource arasında bir köprüdürler, datasource'dan aldıkları veriyi UI
bileşenlerine(adapter view'lere) yüklerler. )
Like Lists (UI Component) gets populated
by using list adapter , from a datasource array.(
Örneğin bir UI bileşeni olan List'ler, list adapter kullanarak array
datasource'dan okudukları veriyi listview ui'a yüklerler. )
Adapters are basically used to deliver
content. One adapter you probably have in every application is the
CursorAdapter which enables you to deliver content given by a cursor from a
database query. A ListView has nearly always some sort of Adapter. ( Adapter'ler genellikle içeriği datasource'dan alıp bir UI bileşenine(adapter view'lere) yüklemek için kulanılır. CursorAdapter, hemen hemen tüm uygulamalarda kullanılan bir adapter
çeşididir mesela, bir veri tabanındaki sorguyu kullanarak elde ettiği
içerikleri bir ui bileşenine(adapter view'lere)
deliver eder. ListView de bir
sık kullanılan bir adapter çeşididir. )
Adapters in Android are a bridge between
the Adapter View (e.g. ListView) and the underlying data for that view. Imagine
what would have been the world without adapters! These are a smart way to
connect a View with some kind of data source. Typically, your view would be a
ListView and the data would come in form of a Cursor or Array. So adapters come
as subclasses of CursorAdapter or ArrayAdapter. (Adapter'ler,
Adapter View ve datasource arasında bir koprüdür. ListView bir Adapter
View'dir, ListView view en çok kullanılan adapter view'lerden biridir.
Adapter olarak genellikle CursorAdapter veya ArrayAdapter kullanılır. Genellikle çoğu adapter bu
2 adapter'ün subclass'ıdırlar. )
11.3 - Adapter
is the link between Data source and AdapterView
http://www.vogella.com/tutorials/AndroidListView/article.html
Adapters are the link between a set of
data and the AdapterView that displays the data. (
Bir adapter ne iş yapar? datasource'dan aldığı verileri child view'lere yükler.
child view'leri viewgroup'a verir. ekranda viewgroup gösterilir.
Yani bir adapter,
veri kaynağı ile veriyi gösteren AdapterView UI'ı
arasındaki bağlantıyı sağlar.)
AdapterView
AdapterViews
are ViewGroups that display child views given to it by an adapter. An example
of an AdapterView is a ListView.( AdapterView, bir Viewgroup'dur. Yani bir veya daha fazla view içerebilir, bu single
view'leri ise bir adapter sağlar. Bir AdapterView, bir adapter'in sağladığı child
view'leri içeren bir Viewgroup'dur. )
Adapters
also provide the child views that display the data in the AdapterView. Adapters
are responsible for supplying the data and creating the views representing each
item. ( Adapter'ler, child view'leri sağlarlar.
Adapter'ler, datasource'dan viewgroup'a veriyi sağlamakla görevlidirler ve
viewgroup'daki herbir view'i yaratmak ile görevlidirler. Ekranda gördüğüm bir
listenin tamamı bir viewgroup'dur. Listedeki herbir satır bir View'dir ve
adapter'ler tarafından sağlanır. )
Adapters get the data and pass it, along
with a child view, to the parent AdapterView which displays the child view and
the data. (Adapter'ler, datasource'dan veriyi
alırlar, bu veriyi bir child view'e gömerler ve bu child view'i AdapterView'e
gönderirler. AdapterView örneğin ListView, kendisine bir adapter tarafından
örneğin ArrayAdapter tarafından gönderilen view'lerin listesini gösterir. )
The Android Framework has a set of
native adapters that are easy to use. You can also create your own custom
adapters if you wish. (Android Framework'le
birlikte hazır olarak gelen adapter'ler mevcuttur. Ama istersek kendi
adapter'imizi tanımlamak da mümkündür. )
Android'in hazır adapter'lerinden en sık
kullanılan ikisi şunlardır : ArrayAdapter ve SimpleCursorAdapter.
ArrayAdapter
An ArrayAdapter is an adapter backed by
an array of objects. It links the array to the Adapter View. ( Bir ArrayAdapter'in datasource'u elemanları object olan
bir array'dir. ArrayAdapter, Array'den aldığı verileri child view'lere
yerleştirir, bu childview'leri adapterview'e(bu bir viewgroup'dur) gönderir. )
The default ArrayAdapter converts an
array item into a String object putting it into a TextView. The text view is
then displayed in the AdapterView (a ListView for example). ( default ArrayAdapter, bir array'deki herbir elemanı
String'e çevirip bir textview'e koyar. ArrayAdapter, Child view olan TextView'leri
viewgroup olan AdapterView'e verir. AdapterView textview'leri bir liste halinde
ekranda gösterir. )
When you create the adapter, you need to
supply the layout for displaying each array string. You can define your own or
use one of Android’s, such as: android.R.layout.simple_list_item_1 . ( Adapter'i yaratırken, adapter'in adapterview'e hangi
child view'leri sağlayacağını, yani hangi layout'u kullanacağını belirtmeliyiz.
Child view'ler için kendi tanımladığımız layout'umuzu kullanabilir veya
Android'deki varolan layout'lardan birini kullanabiliriz örneğin android.R.layout.simple_list_item_1 layout'unu kullanabiliriz, bu Android'de built-in
tanımlı bir layout'dur. )
There are alternative constructors that
you can use for more complex layouts. You can also display images instead of
strings. (AdapterView'de string yerine image
göstermek de, veya daha complex layout'lar göstermek de mümkündür. )
CursorAdapter
The CursorAdapter links the data contained
in a Cursor to an AdapterView. ( CursorAdapter,
Cursor'ın içindeki veriyi childview'lere gömüp bu childview'leri Adapter View'e
gönderir. )
Cursors
A cursor is a set of data. You usually
get a cursor when you do a database query. The result of your query is
contained in the cursor. The SimpleCursorAdapter binds the Cursor data to an
Adapter View. You define a layout that controls how each row of data is
displayed. Each row’s view is populated using the column values of the corresponding
row in the cursor. This layout is then displayed in the Adapter View, like a
ListView for example. ( Cursor, bir veri kümesidir.
Genellikle bir veritabanı sorgulaması yaparak elde ettiğimiz veriler bir
cursor'da tutulur, saklanır. SimpleCursorAdapter,
cursor'daki herbir satırdaki veriyi kullanarak bir child view'i doldurur, bu
child view'leri Adapterview'e verir. Adapterview'de
gösterilen herbir satırın layout'una cursor'daki bir satırdaki veriler
yüklenir, Adapter'in tek tek hazırladığı bu child view'lerın hepsi
Adapterview'de gösterilir.)
----http://www.vogella.com/tutorials/AndroidListView/article.html------
ListView is capable of displaying a
scrollable list of items. ( ListView, item'ların scrollable bir listesini
gösterebilme yeteneğine sahiptir, yani liste ekrana sığmıyorsa aşağı-yukarı
kaydırarak listenin tümünü görebiliriz. )
An adapter extends the BaseAdapter
class. ( Tüm adapter class'ları BaseAdapter
class'ının bir subclass'ıdır. Dolayısıyla kendi class'ımızı tanımlamak
istiyorsak, BaseAdapter class'ını extend eden bir class tanımlamalıyız. )
Every line in the widget displaying the
data consists of a layout which can be as complex as you want. A typical line
in a list has an image on the left side and two text lines in the middle as
depicted in the following graphic. ( AdapterView'de
gösterilen herbir satırın layout'unu istediğimiz şekilde tasarlayabiliriz. Örneğin
listview'deki bir satırda genellikle, en solda bir resim, ortada 2 tane
textview vardır aşağıda gösterildiği
gibi. )
A layout file for a such a line might
look like the following. (Listview'deki bir satırın
layout'unun yukarıdaki gibi olması için, aşağıdaki layout dosyası yazılır. Her
iki TextView'i de ImageView'in sağına koyarız. firstLine id'li TextView'i,
secondLine id'li TextView'in üzerine koyarız. )
The adapter would inflate the layout for
each row in its getView() method and assign the data to the individual views in
the row. (Tanımlayacağımız adapter class'ının
getView() method'u, herbir satırın olmasını istediğimiz layout'u inflate
etmelidir, yani yukarıdaki layout dosyasını inflate etmelidir, yani
inflate('layout_dosyası.xml',...) 'i return etmelidir. Ayrıca, herbir satırın
layout'una source'dan okuduğu verileri yüklemelidir. )
The adapter is assigned to the ListView
via the setAdapter method on the ListView object. (
ListView object'in setAdapter() method'u çağırılarak, bir adapter ListView'e
assign edilir. )
Adapters are not only used by ListView,
but also by other views which extend AdapterView as, for example, Spinner,
GridView, Gallery and StackView. ( Adapter'ler,
AdapterView'ler tarafından kullanılır. Örnek AdapterView'ler şunlardır :
- ListView ,
- Spinner,
- GridView,
- Gallery,
- StackView )
Listener for child views(rows)
To react to selections in the list, set
an OnItemClickListener to your ListView. ( ListView'deki child view'ler yani
satırlar için listener set etmek istiyoruz. Yani bu satırlardan birine
tıklanıldığında yapılmasını istdiğimiz bir aksiyon var. Bunu nasıl yaparız?
ListView object'in setOnItemClickListener() method'unu çağırırız, bu method'a
argument olarak, onItemClick() method'unu içeren bir OnItemClickListener object
veririz, OnItemClickListener object'de onItemClick() method'unu override
ederiz. )
Built-in adapters
Android ile birlikte gelen adapter
implementation'ları vardır. Bunlardan en önemlileri şu ikisidir :
-
ArrayAdapter,
- CursorAdapter
ArrayAdapter can handle data based on
Arrays or java.util.List. SimpleCursorAdapter can handle database related data.( ArrayAdapter, Array ve List'deki verileri okuyup
AdapterView'e yazar. SimpleCursorAdapter
ise veritabanından okuduğu verileri AdapterView'e yazar. )
ArrayAdapter
The ArrayAdapter class can handle a list
or array of Java objects as input. Every Java object is mapped to one row. By
default, it maps the toString() method of the object to a view in the row
layout. (ArrayAdapter, elemanları object olan array
ve list'deki verileri handle edebilir. Array veya list'deki herbir object,
ekrandaki bir satıra karşılık gelir. ArrayAdapter'ün implementation'ında,
object'lerin toString() method'larının return ettiği değer row layout'a
yüklenir. Bu özelliği değiştirmek istiyorsak, ArrayAdapter class'ını extend
eden bir class tanımlamalıyız. )
You can define the ID of the view in the
constructor of the ArrayAdapter otherwise the android.R.id.text1 ID is used as
default. (ArrayAdapter'ün constructor'ında, view'in
id'sini tanımlayabilirsiniz. Tanımlamazsanız default id olan android.R.id.text1
kullanılır. Hangi view'den bahsettiğini anlamadım
adapterview'den mi bahsediyor?? )
The ArrayAdapter class allows to remove
all elements in its underlying data structure with the clear() method call. You
can then add new elements via the add() method or a Collection via the addAll()
method. (ArrayAdapter'ün Array veya List'den veri
okuduğunu söylemiştik daha önce. Yani ArrayAdapter'ün source'u Array veya
List'dir. ArrayAdapter'ün clear() method'unu çağırarak, source'daki tüm
elemanları silebiliriz. ArrayAdapter'ün add() method'unu çağırarak, source'a
yeni bir eleman ekleyebiliriz. ArrayAdapter'ün addAll() method'unu çağırarak, source'a
bir Collection dolayısıyla birden fazla eleman ekleyebiliriz. )
You can also directly modify the
underlying data structure and call the notifyDataSetChanged() method on the
adapter to notify it about the changes in data. (
ArrayAdapter'ün veri okuduğu source'u yani underlying data structure'ı doğrudan
değiştirmek de mümkündür,ancak bu değişiklikten sonra notifyDataSetChanged()
method'unu çağırıp yaptığımız değişikliği adapter'e haber vermeliyiz ki
adapterview güncellensin. Örneğin ArrayAdapter verileri ArrayList'den okuyor
diyelim, bu durumda ArrayAdapter class'ının add,addAll,clear method'larını
çağırarak ArrayList'e elemanların eklenmesini/silinmesini sağlayabiliriz. Veya
ArrayList'de doğrudan bir değişiklik yapabiliriz ancak değişiklik sonrasında
notifyDataSetChanged() method'unu çağırmalıyız. )
If you want to change the data in your
adapter, the underlying data structure must support this operation. This is, for
example, the case for the ArrayList class, but not for arrays. ( ArrayAdapter'ün underlying data structure'ının
yaptığımız ekleme/silme işlemini destekleyip desteklemediğini kontrol
etmeliyiz. Örneğin underlying data structure olarak bir array kullanıyorsak,
yeni bir eleman ekleme işlemini array desteklemez. Buna dikkat etmeliyiz. )
ListView example with ArrayAdapter
Aşağıda
ListView ve ArrayAdapter kullanan bir örnek gösterilmiştir, inceleyelim.
Aşağıda
activity_listviewexampleactivity.xml isimli layout dosyasının içeriği gösterilmiştir. Layout
dosyasında sadece bir ListView element vardır.
The following example shows the usage of
the ListView view in an activity. It uses a default layout from the Android
platform for the row layout. It also demonstrates the removal of list items and
uses animations for the removal. ( Aşağıda bir
Activity class'ı tanımladık. Bu class'da ArrayAdapter'ü extend eden custom bir
adapter class'I tanımladık. Activity class'ının sadece onCreate() method'unu
tanımladık, bu method'u yakından inceleyelim, önce setContentView() method'unu
çağırarak activty'nin layout'u set edilmiştir: setContentView(R.layout.activity_listviewexampleactivity);
Sonra
findViewById() method'unu çağırarak layout dosyasındaki listview element'ini elde
ederiz:
final ListView listview = (ListView)
findViewById(R.id.listview);
Sonra bir String array tanımlarız ve
ArrayString object yaratırız. Sonra array'deki elemanları ArrayList'e ekleriz.
ListView'de kullanacağımız underlying data structure bu ArrayList object'dir.
Activity
class'ının içinde, bir inner class olarak StableArrayAdapter isimli custom bir
Adapter class'ı tanımlarız. Activity class'ının onCreate() method'unda bu StableArrayAdapter class'ından bir object
yaratırız. StableArrayAdapter class'ının constructor'ının 1.parametresi context
object'dir, 2. parametresi listview'deki row'ların layout'udur,
simple_list_item_1 default tanımlıdır Android'de, 3.parametre ise adapter'ün
source'u olan ArrayList object'dir.
final StableArrayAdapter adapter = new
StableArrayAdapter(this,android.R.layout.simple_list_item_1, list);
Elde ettiğimiz
listview object'in setAdapter() method'unu çağırırız. setAdapter() method'una
parametre olarak tanımladığımız StableArrayAdapter class'ından yarattığımız object'i
veririz. Böylece, adapter class'ını ve source'u birbirine bağlamış oluruz,
artık ArrayList'den okuyan adapter ListView'e yazacaktır.
listview.setAdapter(adapter);
Sonra ise,
listview object'in setOnItemClickListener method'unu çağırarak listedeki
elemanlara tıklanınca gerçekleşecek işlemi tanımlarız. ListView'deki bir
elemana tıklayınca, tıklanılan view'e yüklenmiş olan ArrayList elemanı elde
edilir.
final String item = (String) parent.getItemAtPosition(position);
Sonra
ArrayList object'in remove() method'u çağırılarak ilgili eleman, ArrayList'den
silinir.
Yukarıdaki
activity class'ı içerisinde ArrayAdapter object yaratırız. ArrayAdapter class'ının constructor'ına 1.parametre olarak context object'i veririz. Activity
class'ının içindeki this keyword context object'e refer eder.
2.parametre child
view'lerin layout'udur, bu örnekte kullanılan simple_list_item_1 built-in tanımlı bir layout'dur. list isimli array'deki herbir eleman
alınıp simple_list_item_1 id'li view populate edilir. Elde edilen child
view'ler listView isimli viewGroup'da gösterilir.
3.parametre data
source'dur, bu örnekte list isimli bir ArrayList object'dir.
Ayrıca bu activity
class'ı içerisinde bir inner class olarak Adapter class'ı tanımlarız.
Custom
ArrayAdapter class'ında tanımladığımız contructor ve getItemId() method'larını
da inceleyelim. getItemId() method'unun ne iş yaptığını anlamadım için es
geçtim bu kısmı.
Define your own Custom adapter
You can create your custom adapter. For
this you should extend an existing adapter implementation or BaseAdapter class
directly. Frequently you extend ArrayAdapter to write a custom adapter, as this
is simpler than extending BaseAdapter directly. ( Kendi
Adapter class'ımızı tanımlamak mümkündür. Bunun için BaseAdapter class'ını veya
varolan başka bir adapter class'ını extend eden bir class tanımlamalıyız.
Genellikle ArrayAdapter class'ını extend eden bir
class tanımlarız çünkü bu, BaseAdapter class'ını doğrudan extend etmekten daha
kolaydır. Yani tüm adapter class'ları BaseAdapter class'ını extend eder. )
Preparing a row for the list
The adapter needs to create a layout for
each row of the list. The ListView instance calls the getView() method on the
adapter for each data element. ( Adapter, listedeki
herbir eleman için bir layout yaratır(listedeki herbir eleman için adapter
class'ındaki getView() method'u çağırılarak elde edilen layout kullanılır) ve
bu layout'u listedeki ilgili eleman ile doldurur, artık bir child view
hazırdır. Tüm child view'ler bu şekilde tek tek hazırlanıp ListView'e verilir.
Listedeki herbir
eleman için adapter class'ındaki getView() method'u çağırılarak elde edilen
layout kullanılır. Bir adapter data source'dan okuduğu herbir elemanı tek tek
ele alır. Adapter class'ında tanımlı getView() method'unun return ettiği
layout'u ele alır. Sonra bu ikisini birleştirip AdapterView'e verir. Bunu
listedeki tüm elemanlar için yapar. )
In this method the adapter creates the
row layout and maps the data to the views in the layout. Adapter provides data
and defines the layout per row. Within the getView() method you would inflate
an XML based layout and then set the content of the individual views based on
the Java object for this row. ( getView() method'unda herbir
row'un layout'u(view'i) yaratılır ve bu layout'a datasource'dan okunan ilgili
veriler koyulur. )
To inflate the XML layout file, you can
use the LayoutInflator system service. This layout inflator service can get
accessed via the getLayoutInflator() method of the activity or via the
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) method call. ( Bir row'un layout'unu belirlemek
için bir XML dosyasını inflate ederiz. Bunu nasıl yaparız? activity'nin getLayoutInflator() method'unu
çağırarak veya context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
method'unu çağırarak LayoutInflator system service'i(LayoutInflator object'i)
elde ederiz. Sonra LayoutInflater object'in inflate() method'unu çağırarak
ilgili row'un layout'unu belirleriz. LayoutInflater object'in inflate()
method'unun aldığı ilk parameter, row'un layout'unu belirleyen XML dosyasıdır.
)
After the adapter inflated the layout,
it searches for the relevant views in the layout and fills them with the data. ( Adapter, bir row'un layout'unu inflate
ettikten(yarattıktan) sonra, bu layout'daki bazı view'lere veriler koyar. )
The individual elements in the layout
can be found via the findViewById() method call on the top level view. ( Row'un layout'undaki view'lere erişmek için,
inflater.inflate() method'unun return ettiği object'in findViewById() method'U
çağırılır. )
Example of a custom adapter
The following code shows an
implementation of a custom adapter. This adapter assumes that you have two png
files (no.png and ok.png) in one of your directory]]res/drawable folders.
The coding inflates an XML layout file,
finds the relevant views in the layout and sets their content based on the
input data. ( Aşağıdaki örnekte custom bir
adapter'ün implementation'ı gösterilmiştir. res/drawable klasörü altında no.png
and ok.png isimli 2 tane resim olduğu varsayılmıştır.
Datasource'dan elde edilen herbir satırlık veri için getView() method'u
çağırılarak row layout'u inflate edilir(yaratılır), sonra bu row layout'undaki label ve icon id'li
view'ler bulunup bu view'lere veriler yüklenir, iPhone string'i ile başlayan array elemanı için no
id'li resim ekrana yüklenir, otherwise ok
id'li resim ekrana yüklenir. getView() method'u, inflater.inflate() method'unun return ettiği object'i return eder. )
import
...
ArrayAdapter<String>'ü extend eden, MySimpleArrayAdapter isimli bir class tanımlarız. Bu class'ın scope'unda bir
string array declare edilir, adapter'ümüz bu array'den veri okuyacaktır, yani
adapter'ümüzün source'u bu array'dir, yani adapter'Ümüzün underlying data
structure'ı array'dir. Contructor'ın aldığı 2. parametre'deki array'i values
isimli array'e assign ederiz.
getView()
method'unda, LayoutInflater object'i elde ederiz. Sonra bu object'İn inflate()
method'unu çağırarak row'un layout'unu elde ederiz. herbir row'un layout'u
rowlayout.xml'de tanımladığı şekilde gözükür ekranda.
View rowView = inflater.inflate(R.layout.rowlayout, parent,
false);
Sonra bu view
object'in findViewById() method'larını çağırarak rowLayout.xml'deki TextView ve ImageView'e
erişebiliriz. 0. pozisyondaki satıra 0.index'deki array'in değerini alıp
textView'de gösterilen text'i set ederiz ve imageView'e bir resim yükleriz. 1.
pozisyondaki satıra 1.index'deki array'in değerini alıp textView'de gösterilen
text'i set ederiz ve imageView'e bir resim yükleriz. 2. pozisyondaki satıra
2.index'deki array'in değerini alıp textView'de gösterilen text'i set ederiz ve
imageView'e bir resim yükleriz :
TextView
textView = (TextView) rowView.findViewById(R.id.label);
ImageView
imageView = (ImageView) rowView.findViewById(R.id.icon);
textView.setText(values[position]);
//
change the icon for Windows and iPhone
String
s = values[position];
if
(s.startsWith("iPhone")) {
imageView.setImageResource(R.drawable.no);
}
else {
imageView.setImageResource(R.drawable.ok);
}
Updating the data model from the adapter
The row can also contain views which
interact with the underlying data model via the adapter. For example, you can
have a Checkbox in your row layout and if the Checkbox is selected, the
underlying data is changed.( Bir AdapterView'deki
bir satır öyle bir view içerebilir ki bu view data model ile etkileşimdedir.
Örneğin, row layout'unda bir checkbox var diyelim. checkbox'ı seçince(tick
koyunca), underlying data değişir. Yani adapterview'deki bir satıra tıklayınca
adapter'ün source'u modify edilebilir.)
ListActivity and ListFragment
Default container for using ListView
Android provides specialized fragment
and activity classes to simplify list handling. (
Android, listeleri kolaylıkla ele alabilmemiz için bize hazır fragment
class'ları and activity class'ları sunar. Örneğin, ListActivity ve ListFragment
class'larını sunar. )
The classes are the ListActivity class
if you want to use lists in activities and the ListFragment class if you want
to use lists in fragments. (Eğer bir activity'de liste kullanmak istiyorsak
ListActivity class'ını kullanabiliriz. Eğer bir fragment'da liste kullanmak
istiyorsak ListFragment class'ını kullanabiliriz. )
You do not have to assign a layout to
these elements. If you do not define a layout, the activity or fragment
contains a single ListView by default. Both classes allow you to set the
adapter to the default ListView via the setListAdapter() method. ( ListActivity veya ListFragment class'ı ile birlikte
kullanılan default layout(AdapterView) ListView'dir. Manual olarak bir
AdapterView belirtmezsek, default olarak ListView kullanılır. ListActivity veya
ListFragment'ın setListAdapter()
method'unu çağırarak adapter'ün ListView'e(ListView bir adapterView'dir ve
ViewGroup'dur) bağlanması sağlanır. )
ListActivity and ListFragment also allow
you to override a onListItemClick() method for handling selection of list
items. ( ListActivity veya ListFragment class'ının
onListItemClick() method'unu override ederek, listedeki elemanlara tıklanınca yapılmasını
istediğimiz işlemleri belirtiriz. )
The following example code shows a
simple ListFragment implementation. ( Aşağıdaki
örnekte basit bir ListFragment implementation gösterilmiştir.
onActivityCreated() callback method'unda, values
isimli array tanımlanmıştır bu array datasource olarak kullanılacaktır adapter
tarafından.
ArrayAdapter
class'ından bir adapter object yaratılır, row'ların layout'u olarak built-in
layout xml olan simple_list_item_1
kullanılacaktır. Yani herbir row bu layout ile oluşturulup values array'indeki bir eleman ile
doldurulacaktır.
Sonra adapter
object setListAdapter() method'una
argument olarak verilecektir, setListAdapter() method'u çağırılarak adapter'den gelen
child view'lerin ListView viewgroup'a konulması komutu verilir, yani bu method
listview adapterview'inin kullanılacağını belirler.
onListItemClick() method'unda listview'deki herbir
elemana tıklanınca gerçekleştirilecek action belirlenir. onListItemClick() method'unun aldığı 3.parametre olan position, datasource'daki
kaçıncı elemanın ele alındığını gösterir.
)
package
de.vogella.android.fragments;
import
...
public
class MyListFragment extends ListFragment {
@Override
public void
onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String[] values = new String[] { "Android",
"iPhone", "WindowsMobile","Blackberry",
"WebOS", "Ubuntu", "Windows7", "Max OS
X","Linux", "OS/2" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
...
}
}
Exercise: ListView and
ListActivity
Aşağıdaki
örnekte basit bir ListActivity implementation gösterilmiştir. Yukarıdaki aynı
kodlar onCreate() callback method'unda yazılmıştır.
In this example, you use the predefined
ArrayAdapter class and an existing Android layout for the rows. Note that the
setContentView() method is not used. ( Aşağıdaki
örnekte bir ListActivity'de ListView'i nasıl kullanacağımızı görüyoruz. MyListActivity isimli bir activity yaratalım. Adapter olarak built-in
class olan ArrayAdapter class'ını kullanalım. Kullanmak istediğimiz adapter'in okuyacağı
datasource, string içerdiği için new ArrayAdapter<String> diye object yaratırız. ListView'deki herbir row'un
layout'unu, simple_list_item_1 isimli built-in xml layout dosyası belirlesin. setContentView()
method'unun kullanılmadığına dikkat edelim. )
package
de.vogella.android.listactivity;
import
...
public
class MyListActivity extends ListActivity
{
public void
onCreate(Bundle icicle) {
super.onCreate(icicle);
String[] values = new String[] { "Android",
"iPhone", "WindowsMobile","Blackberry",
"WebOS", "Ubuntu", "Windows7", "Max OS
X","Linux", "OS/2" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
}
@Override
protected void
onListItemClick(ListView l, View v, int position, long id) {
String item
= (String) getListAdapter().getItem(position);
Toast.makeText(this, item
+ " selected", Toast.LENGTH_LONG).show();
}
}
Exercise: ListActivity with
custom layout
In our example you will define your
layout for the rows and use it in your adapter. Create the rowlayout.xml layout
file in the directory res/layout folder of the project. ( ListView'de gösterilecek row'lar için custom bir layout
belirleyelim. res/layout klasörü altında rowlayout.xml isimli bir dosya
yaratalım. Bu dosya herbir row'un layout(UI)'unu belirler. rowlayout.xml'de
root element LinearLayout'dur. LinearLayout için default orientation olan
horizontal orientation kullanılır. Yan yana bir ImageView ve TextView element
koyulur. )
rowlayout.xml :
<?xml
version="1.0" encoding="utf-8"?>
<LinearLayout
... >
<ImageView
android:id="@+id/icon"
android:src="@drawable/ic_launcher" >
</ImageView>
<TextView
android:id="@+id/label">
</TextView>
</LinearLayout>
Change
your activity so that is using the new layout. ( ListActivity class'ını
extend eden bir class tanımlarız. Bu class daha önce tanımladığımız ve
listview'deki herbir row için default layout'u kullanan class'a benzer. O
class'da şu şekilde bir ArrayAdapter object yaratmıştık : ArrayAdapter<String> adapter = new
ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, values);
Row'lar için custom
layout set eden bu class'da ise, herbir row için custom bir ArrayAdapter object
şöyle yaratmıştık : ArrayAdapter<String> adapter = new
ArrayAdapter<String>(this, R.layout.rowlayout, R.id.label, values);
Not
: android.R.layout.simple_list_item_1, herbir row
için default olarak kullanılan simple_list_item_1.xml dosyasıdır. setListAdapter() method'u
çağırılarak default AdapterView olan Listview'in kullanılması komutunu veririz.
)
MyListActivity.java :
package
de.vogella.android.listactivity;
import
...
public
class MyListActivity extends ListActivity {
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
String[] values = new String[] {
"Android", "iPhone",
"WindowsMobile","Blackberry", "WebOS",
"Ubuntu", "Windows7", "Max OS
X","Linux", "OS/2" };
// use your custom layout
ArrayAdapter<String>
adapter = new ArrayAdapter<String>(this,
R.layout.rowlayout, R.id.label, values);
setListAdapter(adapter);
}
@Override
protected void
onListItemClick(ListView l, View v, int position, long id) {
String item = (String) getListAdapter().getItem(position);
Toast.makeText(this, item + " selected",
Toast.LENGTH_LONG).show();
}
}
Example: Implementing your custom adapter
Aşağıdaki örnekte ArrayAdapter<String> class'ını
extend eden custom bir adapter class tanımlanmıştır, yani kendi adapter
class'ımızı tanımladık istediğimiz şekilde. "no.png" and "ok.png" diye 2 farklı
resim kullanılmıştır, bu resmler "res/drawable-mdpi" klasörüne
koyulmuştur.
Bu uygulamanın
icon'unu ise siz kendiniz yaratmalısınız, paint'de icon.png diye bir
dosya hazırlayarak yapabilirsiniz bunu.
Bu örnekte, şöyle diyerek
bir LayoutInflater object elde
ettik : (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Sonra bu object'in inflate() method'unu
çağırdık, bu method'a ilk argument olarak row layout xml dosyasını
verdik, bu method bize row view'i yani herbir row için kullanılacak
view'i return eder. rowView object'in findViewById() method'unu
çağırarak row'un layout'undaki bir id'ye sahip olan view'i elde edebiliriz.
Örneğin, TextView textView = (TextView)
rowView.findViewById(R.id.label); diyerek
rowView object'deki yani rowlayout.xml'deki label id'li TextView object'i elde ederiz. Benzer şekilde ImageView object'i elde
ederiz. textView.setText(values[position]); diyerek textView object'e bir
string set ederiz, values array'inin position'ıncı indexindeki string'i set ederiz. values array'inin position'ıncı
indexindeki string, Windows7 , iPhone , Solaris ile başlıyorsa, bu row'daki
ImageView object'e no.png resmini koyarız.
package
de.vogella.android.listactivity;
import
...
public
class MySimpleArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
public MySimpleArrayAdapter(Context
context, String[] values) {
super(context,
R.layout.rowlayout, values);
this.context = context;
this.values = values;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout,
parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
textView.setText(values[position]);
// Change the icon for Windows
and iPhone
String s = values[position];
if (s.startsWith("Windows7") ||
s.startsWith("iPhone")||s.startsWith("Solaris")) {
imageView.setImageResource(R.drawable.no);
} else {
imageView.setImageResource(R.drawable.ok);
}
return rowView;
}
}
To use this adapter, change the activity
to the following. ( Yukarıda custom bir adapter
tanımladık. Aşağıdaki activity class'ında bu adapter'i kullanalım. Önceki örneklerde, default row layout xml'i
olan simple_list_item_1.xml'i ve ArrayAdapter'ü kullanarak şöyle object yaratıyorduk: ArrayAdapter<String>
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, values);
Aşağıdaki örnekte
ise row'ların layout'unu custom adapter class'ı içinde zaten belirlediğimiz
için parametre olarak row'ların layout'unu vermeye gerek yoktur. Dolayısıyla MySimpleArrayAdapter adapter = new MySimpleArrayAdapter(this, values); diyerek arrayadapter object yaratırız.
)
import
...
public
class MyListActivity extends ListActivity {
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
String[] values = new String[] {
"Android", "iPhone",
"WindowsMobile","Blackberry", "WebOS",
"Ubuntu", "Windows7", "Max OS
X","Linux", "OS/2" };
MySimpleArrayAdapter
adapter = new MySimpleArrayAdapter(this,
values);
setListAdapter(adapter);
}
}
If you run this example you should get a
list with different icons for the certain elements. (
Bu programı çalıştırınca, herbir satırdaki text'e bağlı olarak farklı satırlarda
farklı icon'lar görürüz. )
11.4 - Complete
Example-10_4_Adapters_ListView_ArrayList_tobeaddedtosourcecodes
http://serkancay.com/index.php/2016/03/10/android-listview-ozellestirme-ve-tasarim/
https://github.com/serkancay/ListViewDesign
Kisi diye bir class tanımlarız. Bu class
herbir satırda gösterilecek kişinin ismini, soyisimini, şehirini, ilgialani ve profil resminin path'ine refer eden
integer değeri bilgilerini tutmak için kullanılır.
Kisi.java :
public class Kisi { // Kişi sınıfımız kişiye ait özellikler içeriyor. private String ad; private String soyad; private String sehir; private String ilgiAlani; private int resimId; // ornek : R.drawable.ritchie_profile. bu bir int'dir. R.java class'ında tanımlanır otomatik olarak bunun int degeri. public Kisi(String ad, String soyad, String sehir, String ilgiAlani, int resimId) { this.setAd(ad); this.setSoyad(soyad); this.setSehir(sehir); this.setIlgiAlani(ilgiAlani); this.setResimId(resimId); } // Getter setter metodlar public String getAd() { return ad; } public void setAd(String ad) { this.ad = ad; } public String getSoyad() { return soyad; } public void setSoyad(String soyad) { this.soyad = soyad; } public String getSehir() { return sehir; } public void setSehir(String sehir) { this.sehir = sehir; } public String getIlgiAlani() { return ilgiAlani; } public void setIlgiAlani(String ilgiAlani) { this.ilgiAlani = ilgiAlani; } public int getResimId() { return resimId; } public void setResimId(int resimId) { this.resimId = resimId; } }
MainActivity.java
MainActivity class'ının onCreate() method'unda
önce activity_main.xml dosyası
kullanılarak layout set edilir. Sonra bu layout'daki ListView object elde edilir. Sonra, Kisi object'leri içerecek bir ArrayList object tanımlarız. Sonra Kisi class'ından object'ler yaratırız ve bu
object'leri arraylist'e
ekleriz. Sonra kendi tanımladığımız custom adapter class'ı olan ListAdapter class'ından bir object yaratırız, bu
object'i yaratırken constructor'a arraylist object'i veririz. Sonra hangi listview'in içerisine
içerik yüklemek istiyorsak, o listview'e karşılık gelen View object'in setAdapter() method'unu
çağırırız, setAdapter() method'una argument olarak ListAdapter class'ından yarattığımız object'i
veririz.
Ayrıca,
MainActivity class'ının scope'u içerisinde, ListView, ListAdapter ve
ArrayList'e refer eden reference variable'ları declare ettik.
ListAdapter.java :
BaseAdapter class'ından
extend eden ListAdapter isimli bir
custom adapter class'ı tanımlayalım. ListAdapter class'ının
scope'u içerisinde, ArrayList object'e, LayoutInflator object'e ve Context object'e refer eden reference
variable'ları declare ederiz.
ListAdapter class'ının constructor'ında, ArrayList object'i, LayoutInflator object'i ve Context object'i set ederiz.
BaseAdapter
class'ını extend ettiğimiz için, getCount(), getItem(),getItemId()
method'larını da implement ettik, ayrıntıya girmiyorum burda gerekli olursa
ekstra araştırma yaparsın. ArrayAdapter veya CursorAdapter'ü extend eden bir
adapter class'ı tanımlamak istersen bu method'ları implement etmene gerek yoktur.
getView() method'unun implementation'ına bakalım.
ListView'deki herbir satirın layout'unun satir_tasarimi.xml'deki şekilde olmasını şöyle
ayarlarız : View satirView = layoutInflater.inflate(R.layout.satir_tasarimi, null);
Sonra satirView isimli object'in findViewById() method'unu çağırarak satırdaki view object'leri tek tek elde ederiz: satirView.findViewById().
Sonra satirView isimli object'in findViewById() method'unu çağırarak satırdaki view object'leri tek tek elde ederiz: satirView.findViewById().
getView() method'unun aldığı 1. parametre olan position çok
önemlidir. Ekrandaki ListView'de gösterilen satırın pozisyonunu temsil eder.
Örneğin 5 tane elemanı olan bir liste varsa elimizde ekranda 0'dan 4'e kadar
pozisyonlarda satırlar gösterilir ListView'de. Dolayısıyla ArrayList'in i.
index'indeki elemana ListView'in i. pozisyonundaki satır karşılık gelir.
final Kisi kisi = list.get(position);
ImageView object'in
setImageResource() method'unu
çağırarak, ImageView'e bir image koyarız. TextView object'in setText() method'unu çağırarak, TextView'e bir
text set ederiz. ButtonView object'in setOnClickListener() method'unu çağırarak, buton tıklanınca
çağırılacak bir method tanımlarız.
public class ListAdapter extends BaseAdapter { // Veri olarak kişi listesini kullanacak. private List<Kisi> list; LayoutInflater layoutInflater; Context context; public ListAdapter(Context context, List<Kisi> list) { this.context = context; // Layout Inflater tanımlanıyor... layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.list = list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position){return list.get(position);} @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // Tasarımını yaptığımız layout dosyamızı view olarak alıyoruz View satirView = layoutInflater.inflate(R.layout.satir_tasarimi, null); // Öğelerimizi satirView'dan çağırıyoruz. ImageView ivKisiResmi=(ImageView)satirView.findViewById(R.id.ivKisiResmi); TextView tvAd = (TextView) satirView.findViewById(R.id.tvAd); TextView tvSoyad = (TextView) satirView.findViewById(R.id.tvSoyad); TextView tvSehir = (TextView) satirView.findViewById(R.id.tvSehir); TextView tvIlgiAlani=(TextView) satirView.findViewById(R.id.tvIlgiAlani); Button btnSelect = (Button)satirView.findViewById(R.id.btnSelect); // Mevcut pozisyon için kisi nesnesi oluşturuluyor. final Kisi kisi = list.get(position); // Öğelerimize verilerimizi yüklüyoruz. ivKisiResmi.setImageResource(kisi.getResimId()); tvAd.setText(kisi.getAd()); tvSoyad.setText(kisi.getSoyad()); tvSehir.setText(kisi.getSehir()); tvIlgiAlani.setText(kisi.getIlgiAlani()); btnSelect.setOnClickListener(new OnClickListener() { public void onClick (View v) { Toast.makeText(context, kisi.getAd() + " " + kisi.getSoyad() + " secildi!", Toast.LENGTH_SHORT).show(); } }); // Mevcut satır için işlem tamam ve view return ediliyor. return satirView; } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout ... >
<ListView android:layout_margin="10dp" android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:dividerHeight="5dp" android:divider="@android:color/transparent"/>
<!-- Burada divider satırların arasını açıyor divider'ın rengini transparent yaptım ve saydam oldu--> </RelativeLayout>
satir_tasarimi.xml
Output
:
11.5 - CursorAdapter with
custom layout
Explanation 1 :
https://coderwall.com/p/fmavhg/android-cursoradapter-with-custom-layout-and-how-to-use-it
Android provides
adapter classes specifically to display data from an SQLite database query.
There is SimpleCursorAdapter class, which is more simpler and you cannot use
your own custom xml layout and you don't have the control of the layout. In
order to use custom xml layout, Android provides CursorAdapter. ( Android 'in bize sağladığı cursoradapter class'ı gibi adapter
class'larını kullanarak, SQLite veritabanından veri çekip AdapterView'e load
edebiliriz. Bu işi yapan en basit class, SimpleCursorAdapter class'ıdır, ancak SimpleCursorAdapter class'ını kullanırsak custom
layout set edemeyiz, default layout'u kullanmak zorunda kalırız. Eğer custom layout kullanmak istiyorsak, CursorAdapter
class'ını kullanmak zorundayız. )
A CursorAdapter makes it easy to use when the
resource of a listview is coming from database and you can have more control
over the binding of data values to layout controls. In the newView() method,
you simply inflate the view and return it. In the bindView() method, you set
the elements of your view. (Listview'deki satırlarda
gösterilecek verilerin veritabanından okunmasını istiyorsak, CursorAdapter
class'ını kullanmalıyız. newView() method'unda, custom layout'u inflate ederiz(belirleriz), yani
newView() method'u satırların layout'u olan View object'i return eder. bindView() method'unda ise, View object'in
yani herbir satırın içindeki view object'lerin içeriğini belirleriz,
örneğin,setText(),setImageResource() gibi method'ları çağırarak yaparız
bunları. )
1) CursorAdapter
- Create a new class which extends CursorAdapter
First, create new
class which extends CursorAdapter and give it a name. This new CursorAdapter
class must implement the inherited abstract methods as following: (CursorAdapter class'ını extend eden bir class tanımlayalım. Bu class, CursorAdapter class'ının abstract
method'larını implement etmek zorundadır.
)
public class MyCursorAdapter extends CursorAdapter {
// Default constructor
public MyCursorAdapter(Context context, Cursor cursor, int flags) {
...constructor implement edilir.
}
public void bindView(View view, Context context, Cursor cursor) {
...
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
...
return null; // View object return edilir.
}
}
Next define the methods of MyCursorAdapter
In BaseAdapter, view is created in getView() method; in CursorAdapter, however, view is created in newView() method and elements are
populated in bindView(). ( BaseAdapter ve CursorAdapter
class'larını extend etmek arasındaki fark şudur:
BaseAdapter class'ını extend eden bir class
tanımlarsak, getView() method'unda view object'i
yaratır ve return ettiririz.
CursorAdapter class'ını extend eden bir class
tanımlarsak, newView() method'unda view object'i
yaratır ve return ettiririz. View object'lere veri yükleme(mesela
setText(),setImageResource()) işini ise bindView() method'unda yaparız. )
In the newView() method, you simply inflate the view of your custom xml and
return it. In the bindView() method, you set the elements of
your view. (newView() method'unda custom xml'in
view'ini inflate edip return ederiz. Bir satıra karşılık gelen View object'in
içerdiği view object'lerin içeriğini belirleme(mesela
setText(),setImageResource()) işini ise bindView() method'unda yaparız. )
Here is code:
Here is code:
public class MyCursorAdapter extends CursorAdapter {
private LayoutInflater cursorInflater;
// Default constructor
public MyCursorAdapter(Context context, Cursor cursor, int flags) {
super(context, c, flags);
cursorInflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
...
}
public void bindView(View view, Context context, Cursor cursor) {
TextView textViewTitle = (TextView) view.findViewById(R.id.articleTitle);
String title = cursor.getString( cursor.getColumnIndex( MyTable.COLUMN_TITLE ) )
textViewTitle.setText(title);
...
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// R.layout.list_row is your xml layout for each row
return cursorInflater.inflate(R.layout.list_row, parent, false);
}
}
( bindView() method'unun aldığı parametre olan View object, newView() method'unun return ettiği View object'dir. Yani bindView() method'unun aldığı parametre olan View object bir satıra karşılık geldiği için, bu View object'in findViewById() method'larını çağırarak satır layout'unun içerdiği view object'leri elde ederiz. Sonrasında ise, veritabanından bir veri çekip bu veriyi view object'lere yükleyebiliriz. )
2) MainActivity
class
Since loading data
from database is heavy-duty job, we will load the data in the Thread. If you do
not explicitly start CursorAdapter in its own thread then it will run on the
main (UI) thread which may be noticeable as jittery or slow to respond
interface by your users. Here we'll use android Handler
class. ( Veritabanından veri çekmek uzun süren bir task
olduğu için, bu işi bir Thread'de yapmalıyız. Aksi takdirde, veritabanından
veri çekme işlemi main thread'de yapılacaktır bu da uygulamanın yavaş
çalışmasına neden olacaktır user experience'ı olumsuz etkileyecektir. )
Aactivity class'ını inceleyelim. Önce main layout set edilir, sonra main layout'daki main_layout id'li element yani ListView object elde edilir. listView = (ListView) findViewById(R.id.main_layout);
Sonra contentResolver object'İn query() method'u çağırılarak, Cursor object elde edilir. Bir Handler object'i yaratılır, bu object'in post method'una anonymous bir Runnable object verilir. Runnable object'in run() method'unda, tanımladığımız MyCursorAdapter class'ının constructor'ı çağırılarak bir object yaratılır, constructor'a 3.argument olarak az önce elde ettiğimiz Cursor object verilir. Sonra, setAdapter() method'u çağırılarak ListView object'in ListView ile adapter birbirine bağlanır.
mCursor = getContentResolver().query( MyAdContentProvider.CONTENT_URI, mProjection, null, null, null);
public class MainActivity extends Activity {
MyCursorAdapter customAdapter;
private Cursor mCursor;
private ListView listView;
// Default constructor
public onCreate(Bundle savedInstanceState) {
...
setContentView(R.layout.activity_main)
listView = (ListView) findViewById(R.id.main_layout);
// Your database schema
String[] mProjection = {
MyTable.COLUMN_ID,
MyTable.COLUMN_TITLE,
};
// Here we query database
mCursor = getContentResolver().query(
MyAdContentProvider.CONTENT_URI,
mProjection,
null,
null,
null);
listView.setOnItemClickListener(new OnItemClickListener() {
...
}):
}
new Handler().post(new Runnable() {
@Override
public void run() {
customAdapter = new MyCursorAdapter(
MainActivity.this,
mCursor,
0);
listView.setAdapter(customAdapter);
}
});
}
Explanation 2:
CursorAdapter
class'ından extend ettiğimiz class'ın iskeleti aşağıdaki gibidir.
newView() method is called to
create a View object representing the rows in the list. Here, you just create
an object don't set any values. ( Herbir satrının layout'unu
set ederiz. Ancak layout'un içeriğini müdahale etmeyiz. )
View returned from
newView() is passed as first parameter to bindView, it is here where you will
set values to display. (newView() method'unun return ettiği View object, bindView()
method'unun 1.parametresine verilir. bindView method'unda 1. parametre ile
gelen object'in içerdiği view object'lere içerik yüklenecektir. )
Worth mentioning is
that bindView is called for each element when it has to be displayed but
newView is not. ( Listedeki herbir satır(item) için, bindView() method'u birer
kez çağırılacaktır ancak newView() method'u sadece 1 defa çağırılacaktır o da
satırların layout'unu inflate etmek için. )
No xml version
If
You choose to create view in Java instead of defining it in xml, your newView()
method will be a bit more complex, but you don't need inflater instance. For
example, if your list will have only one text value to display it could look
like this. ( Satırların layout'unu xml'de değil de java'da yaratmak
istiyorsak, newView() method'u daha karmaşık olacaktır
ancak inflate() method'unu kullanmaya gerek kalmayacaktır. Örneğin listedeki
satırlarda sadece textview olmasını istiyorsak, newView() method'unun
implementation'ı aşağıdaki gibi olmalıdır. )
public class CustomCursorAdapter extends CursorAdapter { @Override public View newView(Context
context, Cursor cursor, ViewGroup parent) { TextView
content = new TextView(context); content.setTag("content"); return content; } |
If You need something more complex
You just follow the regular way of creating view and return it. ( Satırların
layout'unu xml'de tanımladıysak, newView() method'unun implementation'ında
layout xml'i inflate etmeliyiz. )
Bind data
Now it is time to bind data to view
crated in previous step. (Önceki adımda yaratılan view
object'in içerdiği view object'lere veri yüklemek için bindView method'unu
implement ederiz. Bu method herbir satır için çağırılır. )
public class CustomCursorAdapter extends CursorAdapter { @Override public void bindView (View
view, Context context, Cursor cursor) { TextView
content = (TextView) view.findViewById(R.id.row_content); content.setText(cursor.getString(cursor.getColumnIndex(Table.CONTENT))); } |
First You get element to populate by
calling view.findViewById(), cast it to correct type, and set value. Simple.
You go on like this for each value/element You have and wish to display.
You go on like this for each value/element You have and wish to display.
Different colours for odd and even elements
That is quite popular thing and takes
just few line to implement. (Herbir satırı sırayla farklı
renklere boyamak çok basittir ve sıklıkla yapılır geliştiriciler tarafından. Bu
iş için bindView() method'u aşağıdaki gibi implement edilmelidir. )
@Override
public
void
bindView
(View
view, Context context, Cursor cursor) {
if(cursor.getPosition()%2==1) { view.setBackgroundColor(context.getResources().getColor(R.color.background_odd));
}
else
{
view.setBackgroundColor(context.getResources().getColor(R.color.background_even));
}
...
}
We
get cursor's position check its reminder from division by 2, if it is 1 then it
is odd row otherwise it is even.
Returns the current position of the cursor in the row set.
The value is zero-based. When the row set is first returned the cursor will be
at positon -1. ( Cursor.getPosition(), cursor'ın refer ettiği satırın
index'ini return eder.)
Explanation 3 :
In
Android development, any time you want to show a vertical list of items you
will want to use a ListView which is populated using an Adapter to a data
source. When we want the data for the list to be sourced directly from a SQLite database query,
we can use a CursorAdapter. (
Item'ların dikey listesine ihtiyacımız olduğunda, ListView kullanırız. Adapter
bir source'dan okuduğu verileri ListView'deki satırlara yükler. Adapter'in
veritabanından okuduğu verileri listview'e yüklemesini istiyorsak, CursorAdapter
kullanmalıyız. )
The
CursorAdapter
fits in between a Cursor
(data source from SQLite query) and the ListView
(visual representation) and
configures two aspects: (CursorAdapter'ün
veritabanından okuduğu verileri listview'e yükler. Satırların layout'unu
belirler. Hangi view'e ne verisinin load edileceğini tanımlar. )- Which
layout template to inflate for an item
- Which
fields of the cursor to bind to which views in the template
Creating the View
Template
Herbir
satırın layout'u şu olsun :
res/layout/item_todo.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"
android:orientation="horizontal" >
<TextView
android:id="@+id/tvBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Study cursors"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/tvPriority"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="3"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
Defining the Adapter
Next, we
need to define the adapter to describe the process of projecting the
Cursor
's data into a View. To do this we need to override the newView()
method and the bindView()
method. The naive approach to this (without any view caching)
looks like the following. ( CursorAdapter class'ını extend
eden bir class tanımlayalım. Cursor'ın refer satırları elde edip, view
object'lere yükleriz CursorAdapter class'ında.)public class TodoCursorAdapter extends CursorAdapter {
public TodoCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.item_todo, parent, false);
}
// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
@Override
public void bindView(View view, Context context, Cursor cursor) {
// Find fields to populate in inflated template
TextView tvBody = (TextView) view.findViewById(R.id.tvBody);
TextView tvPriority = (TextView) view.findViewById(R.id.tvPriority);
// Extract properties from cursor
String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
int priority = cursor.getInt(cursor.getColumnIndexOrThrow("priority"));
// Populate fields with extracted properties
tvBody.setText(body);
tvPriority.setText(String.valueOf(priority));
}
}
First, we define a constructor that
passes the cursor and context to the superclass. Next, we override the
newView
method, which is used to inflate a new view template. Finally,
we override the bindView
method, which is used to bind all data to a given view to
populate the template content for the item.
Retrieving the Cursor
In order
to use a
CursorAdapter
, we need to query a SQLite database and get back a Cursor
representing the result set. Once you have a database and tables
defined, then we can get access to a Cursor
by querying the database with rawQuery
: ( CursorAdapter'ü kullanabilmek
için, önce bir Cursor object elde ederiz aşağıdaki gibi. )// TodoDatabaseHandler is a SQLiteOpenHelper class connecting to SQLite
TodoDatabaseHandler handler = new TodoDatabaseHandler(this);
// Get access to the underlying writeable database
SQLiteDatabase db = handler.getWritableDatabase();
// Query for items from the database and get a cursor back
Cursor todoCursor = db.rawQuery("SELECT * FROM todo_items", null);
Attaching the Adapter to a ListView
Now, we
can use the
CursorAdapter
in the Activity
to display an array of items into the ListView
: ( ListView view'i elde ederiz.
Tanımladığımız CursorAdapter class'ından bir object yaratırız. ListView
object'in setAdapter() method'unu çağırırak adapter ve listview'i birbirine
bağlarız. )// Find ListView to populate
ListView lvItems = (ListView) findViewById(R.id.lvItems);
// Setup cursor adapter using cursor from last step
TodoCursorAdapter todoAdapter = new TodoCursorAdapter(this, todoCursor);
// Attach cursor adapter to the ListView
lvItems.setAdapter(todoAdapter);
This will then
trigger the
CursorAdapter
iterating through the result set and populating the list.
We can change the
cursor to update the adapter at any time with: (Tanımladığımız
CursorAdapter class'ından yarattığımız object'in içindeki cursor object'i
değitirmek de mümkündür. Bunun için, CursorAdapter object'in changeCursor()
method'unu çağırırız. )
// Switch to new cursor and update contents of ListView
todoAdapter.changeCursor(newCursor);
Explanation 4 :
http://stackoverflow.com/questions/5457699/cursor-adapter-and-sqlite-example
There are two main parts to using a Cursor
Adapter with SQLite:
1. Create a proper Cursor from the Database. ( Veritabanından bir Cursor object
elde et. )
2. Create a custom Cursor
Adapter that takes the Cursor data from the database and pairs it with the View you intend to represent the data with. ( CursorAdapter class'ını extend eden bir class tanımla. Bu
class'dan bir object yarat, yaratırken constructor'a argument olarak 1.adımda
yarattığın Cursor object'i ver. )
1. Create a proper Cursor
from the Database.
In your Activity:
SQLiteOpenHelper sqLiteOpenHelper = new SQLiteOpenHelper(
context, DATABASE_NAME, null, DATABASE_VERSION);
SQLiteDatabase sqLiteDatabase = sqLiteOpenHelper.getReadableDatabase();
String query = "SELECT * FROM clients ORDER BY company_name ASC"; // No trailing ';'
Cursor cursor = sqLiteDatabase.rawQuery(query, null); // Cursor object'i elde ettik.
ClientCursorAdapter adapter = new ClientCursorAdapter(
this, R.layout.clients_listview_row, cursor, 0 ); // Tanımladığımız CursorAdapter class'ından bir object yarattık. Önceki örneklerden farklı olarak, row layout.xml 'i adapter class'ını constructor'ına verdik, adapter class'ının constructor'ında super() method'unun 2.parametresine bu layout'u verdik, yani newView() method'unu tanımlamamıza gerek kalmadı.
this.setListAdapter(adapter); // listview ve adapter'ü birbirine bağladık.
2. Create a Custom Cursor
Adapter.
Note: Extending from
ResourceCursorAdapter
assumes you use XML to create your views. (Eğer row layout'unu java'da değil de xml dosyasında
tanımladıysak, CursorAdapter veya ResourceCursorAadapter class'ını extend eden bir
class yazabiliriz )public class ClientCursorAdapter extends ResourceCursorAdapter {
public ClientCursorAdapter(Context context, int layout, Cursor cursor, int flags) {
super(context, layout, cursor, flags);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView name = (TextView) view.findViewById(R.id.name);
name.setText(cursor.getString(cursor.getColumnIndex("name")));
TextView phone = (TextView) view.findViewById(R.id.phone);
phone.setText(cursor.getString(cursor.getColumnIndex("phone")));
}
}
Hiç yorum yok:
Yorum Gönder