13 Şubat 2018 Salı

Android Dersleri 11.1 - Adapters, ListView, AdapterView nedir ve nasıl kullanılır?


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().
        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:
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.

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 Cursorrepresenting 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