Android 40: JSON Parse

API nədir?

API (Application Programming Interface). Developerlər tərəfindən yaradılmış hazır sinif, prosedur, funksional. Hər hansı application yaradanda digər servisdən istifadə etmək üçün gərək onun API-nı istifadə edərək onunla “communication” yaradıb, hər hansı məlumatı ötürüb götürmək, ümumiyətlə onun necə və nəcür istifade edilməsi qaydalarıdır. Məsələn, mobil üçün twitter tədbiqetməsi yazirsız, twitter account, servisdən istifadə etmək üçün gərək bu application twitter api da qurulumuş qaydaları ilə onunla “əlaqə” qursun, məlumat qəbul edib ötürülsün. [1]

API (a techie term for application programming interface – interfeys proqram əlavəsi üçün olan ifadə) istifadəçilərə bir başa səhifələrində məlumat almağa imkan yaradaraq fasiləsiz yeniləmələr təmin edərək müntəzəm yükləmələr, məlumat axını-mətn, rəsmlər, görüntü üçün video ilə təchiz edir. Məsələn, Flickr API-si sizə bloqunuzdan və ya səhifənizdən şəkilləri görüntüləməyə imkan yaradır. Twitter və Facebook kimi saytlar API-ni “açın” edəndə,bu o deməkdir ki, veb tərtibatçılar əsəs xidmətlər üzərində yeni funksiyalara əsaslanan tətbiqi proqramlar yarada bilərlər.(Wikipedia entry baxın) [2]

JSON nədir?

JSON (“JavaScript Object Notation”) — insanlar tərəfindən oxuna bilən verilənlərin çevrilməsi üçün formatdır. XML-in Javascript ilə daha yaxşı işləyə bilməməsindən yaranmışdır. JSONda verilənlər açar(key) və dəyər(value) dan ibarət olur. XML-dən asan olmasına görə müasir dövrdə yavaş-yavaş XML-i əvəzləməyə başlamışdır. XML-dən daha sürətlidir. Əsas üstünlüyü verilənlərin transferi zamanı daha kiçik hissələrdən istifadə edə bilməsidir. Fayl Genişlənməsi .json-dur. [3]

JSON Obyect nədir?

JSON Obyektləri iki yerə ayrılır – “{” və “}” olmaqla, dalğalı mötərizə daxilindəkiləri də əhatə etməklə bütünlükdə bir obyekt, ikincisi isə açar-dəyər cütlüyü. [4]

JSON Array nədir?

Array – yəni massiv olub “[” və “]” olmaqla, kvadrat mötərizə ilə başlayıb bitir.  [5]

Qısa infarmasiyadan sonra keçək əsas məsələyə. Bu yazımızda https://jsonplaceholder.typicode.com/posts adresindəki JSON-u parse edəcəyik.

İlk öncə MainActivity-də String jsonText = “”; dəyişəni yaradıb dırnaq arasına öz lindəki JSON mətnin kopyalayıb yapışdıraq. (Qeyd: Növbəti yazıda artıq mətni yox, sadəcə linki yazacağıq, linkdən JSON mətnini almağa çalışacağıq). JSON mətninə uyğun bir model yaradaq, hansı ki List (əlaqədar yazının linki) yazılarında yaratmışdıq.

UserModel adlı java faylı yaradırıq, 4 dəyişənimizi əlavə edib ona uyğun get və set metodlarını yazırıq.

İndi qayıdaq MainActivity-yə və JSON mətnimizi parse edək. Bunun üçün Modelimizin arrayListini yaradırıq.

ArrayList<UserModel> arrayList = new ArrayList<>();

Kodumuzdakı JSON Parse hissəsini try/catch içində yazacağıq.

Əvvəlcə JSONArray yaradııq, içinə mətnimizi ötürürük. Sonra dövür qururuq, i sıfırdan jsonArray.length()-ə qədər. Həmin dövrün içində massivin içindən götürürük, modelimizi yaradıb müvafiq əmirləri yerinə yetiririk. Kodun qalan hissəsi şəkildəki kimidi.

Burada biz JSON mətninə uyğun hər bir dəyişənimiz üçün dövr daxilində getİnt və getString edərək müvafiq int və String dəyişənlərinə mənimsətdik, onları da modelə ötürdük, sonar modelimizi arraylistimizə ötürdük.

Bu yazıda əsas göstərmək istədiyim hissə JSON parse idi, adepter qrup, həmin aldığımız məlumatları listView daxilində ekrana çıxartmaq da sizin ev tapşırığınız olsun. Kodalrı vermiyəcəm. Uğur ola!

Mənbələr:

[1] https://cavablar.net/2015/01/05/api-n%C9%99dir/#.Wz_TzCC-m00
[2] http://sosialmedia.net/?p=1145
[3] https://az.wikipedia.org/wiki/JSON
[4] https://www.w3schools.com/js/js_json_objects.asp
[5] https://www.w3schools.com/js/js_json_arrays.asp

Advertisements

Android 39: SQLite

Ötən yazımızda bir listimiz var idi, xatırlayırsınızsa. Əvvəldən üzərində hazır şagird informasiyaları qeyd edilmişdi. Sonra əlavə et düyməsininə basaraq yenlərini əlavə edirdik. Lakin bir problem vardı orda. Tədbiqetmədən çıxıb, yenidən başltdıqda əlavə etdiklərimiz harda olurdu? Heçarda. Silinib getmişdi. Nətər olur? O boyda əzyətlə əlavə etdiklərimiz hanı? Olmaz axı belə.

Demək elə bir şey etməliyik ki, həmin listimiz yaddaşda qalsın. İstədiyimiz vaxt istifadə edə, əalvələr edə bilək.

Bax elə bunun üçün də Android telefonların üzərində hazır gələn SQLite-dan istifadə edəcəyik.

Bunun üçün həmin layihə üzərindən yeni bir sinif yaradırıq. Mən adını DBHelper qoyuram, siz istədiyiniz adı qoya bilərsiniz. Əsas odu, adını görəndə nə məna verdiyi başa düşəsiniz. (“Asdfggh” – qoymayın yəni).

Sinfimiz’ “SQLiteOpenHelper” sinfini extends edirik. Sonra isə implement etməli olduğumuz konstruktor və onCreate()/onUpgrate() metodları var.

İndi bizə lazım olan dəyişənləri yaratmaq lazımdır.

Yaratdığımız metodalra və dəyişənlərə baxaq.

  • DBHelper(…) – bizim konstruktor metodumuzdur. Verilənlər bazası ilə necə əlaqə quracağımızı göstərir.
  • onCreate – Verilənlər bazası üçün cədvəlləri yaratmaq üçün istifadə edilir.
  • onUpgrade – versiyan yeniləmək üçün istifadə edilir. (Sizin 3 sətriniz var, versiya kodunuz 1dir, sonra sətirlərin sayını artırdıqda versiya kodunuzu dəyişməsəz SQLite işləməyəcək. Versiya kodu dəyişdirilərkən edilməli olan proseslər bu metodda yazılır).

 

  • DB_VERSION – Versiya kodumuzu saxlayır.
  • DB_NAME – Verilənlər bazasın adınıs axlayır
  • TB_STUDENT – cədvəlin adını saxlayır

Digər 4ü isə cədvəldə uyğun olaraq şagirlərin sırasını (id), adını, soyadını və sinif nömrısii saxlayır.

İndi konstruktorumuz üzərində kiçik dəyişiklik edək.

Qeyd: Kodları sonda verəcəm, indilik əliniz öyrəşsin deyə siz yazın. Bunun üçün də şəkilləri yerləşdirirəm.

Konstruktorumuzun arqumentlərini azaldıb, həmin informasiyaları öz dəyişənlərimizdən aldıq. Məncə indi konstrukdor daha aydın olar sizə (hansı arqument nədir deyə).

Gəlin indi Cədvəlimizi yaradaq. Verilənlər bazası ilə işləyənlər bilər, indi “CREATE TABLE” əmri ilə müvafiq sütunlarımızı yaradacağıq.

Kod sətirimiz string daxilində belə olmalıdır:

"CREATE TABLE TB_STUDENT(STUDENT_ID int primary key, STUDENT_NAME text, STUDENT_LAST_NAME text, STUDENT_CLASS text)"

Qeyd: burada “primary key” –  təkrarlanmayan dəyərlər üçün istifadə edilir, hər bir cədvəldə sadəcə bir sütun üçün işlədilə bilər.

İndi biz yuxarda görüdüyümüz stringin içində yazılan bəzi adları hazır dəyişənlərimizdən çağıracağıq. Çünki zamanla əgər cədvəldəki hər hansı bir sütunun adı dəyişdirilərsə o zaman bütün kodlardakı adları yox, sadəcə bir yerdən – təyin etdiyimiz yerdən dəyişdirmək kifayət etsin.

SQLiteDatabase-in execSQL metodundan istifadə edərək cədvəliizi yaradaq:

Yuxardakı execSQL metodu istifadə edərəm onUpgrade metodumuz üçün cədvəli silmə və yenidən yaratma prosesini yazaq:

Bu hissəsi hazır. Gəlin indi DBHelper sinfimizə “AddStudent” metodu əlavə edək, bu metod vasitəsiylə bazaya yeni sətirlər əlavə edəcəyik. Bu metod bizdən student obyekti tələb etsin.

getWritableDatabase() – metodu verilənlər bazasına məlumat əlavə etmək üçün istifadə olunur.

İndi qayıdaq MainActivity-yə. Listimizi, adapterimizi silək. DBHelper üçün qlobal obyektimizi yaradaq:

DBHelper dbHelper = new DBHelper(MainActivity.this);

Adapterimizi isə aşağdıdakı kimi təyin edək:

adapter = new Adapter(MainActivity.this, dbHelper.getAllStudent());

Burada getAllStudent metodun hələ yazmamışıq. Bu metod vasitəiylə verilənlər bazasından listimizi alacağıq. Bunun üçün DBHelper sinfinə keçid edək və bizə ArrayList qaytaracaq olan metodumuzu yazaq:

Verilənlər abzasına veriənlərimizi əlavə edərkən necə ki getWritableDatabas metodundan istifadə etdik, indi də getReadableDatabase() metodundan istifadə edəcəyik.

Cursordan istifadərək “rawQuery” metodun çağıraq. Bu metod verilənlər bazası üçün müəyyən əmirləri etməyimizə bizə kömək edəcək. Edəcəyimiz əmir şagirdlər cədvəlindəki bütün informasiyanı çağırmaq üçündür. Bayaq ArrayList-imizi (“ArrayList<Student> arrayList = new ArrayList<>();”) MainActivity-dən silmişdik, burada yazaq. Cursorun sonuncu sətirə düşənə qədər ediləcək prosesləri while içərisində yazaq. Belə ki, Şagird metodu yaradıb, getColumnIndex metodalrı ilə müvafiq dəyişənləri cursordan alıb yaratdığımız Şagird obyektinə ötürürük. Sonra həmin obyekti listə “add” edirik, cursoru növbətinə keçirirk. Dövr bitəndən sonra cursoru “close” etmək yaddan çıxmasın. Metodumuz yaratmış olduğumuz arraList-i “return” edəcək. Kod aşağıdakı kimidir:

İndi nə edirik? MainActivity-yə qayıdırıq, onActivityResult içərisində dəyişikliyimizi edək.

Burda nə etdik biz? Adapter daxilindəki “RefreshArray” metoduna dbHelperin obyektini ötürdük. Axı Adapterdə helə bir metod yox idi. Onda gedək yazaq:

Son iki dəyişikliyimizə bir daha baxaq. İstifadəçi “add” buttonuna basarkən həmin sinif açılacaq, istifadəçinin daxil etdiyi məlumatalr verilənlər bazasına ötürüləcək. Son iki dəyişikliyimizə görə: istifadəçi əsas səhifəyə qayıdarkən (əlavə etmə səhifəsində “finish”-ə basdıqdan sonra) avtomatik olaraq tədbiqetmə ilk yaradılarkən baş verdiyi kimi məlumat bazasına sorğu göndərib ordan informasiyaları alıb listimizdə göstərəcəyik.

Tədbiqetməmizi işə salaq: error verdi helə? Çünki AddActivity daxilindəki kodalrda dəyişiklik etməmişik axı.

Qlobal şəkildə dbHelper obyektini yaratmaq yaddan çıxmasın ()

İndi tədbiqetməmizi işə salaq:

Yazılar çox qarışıqdı. İnternetdə mənbələr boldu, lakin hamısı xırda fəqlərlə bir-birindən ayrı görünür. Türk dilində bir neçə mənbə tapmışam sizlər üçün, istəsəz onlara baxın. Əvvəl mən kodlarımı verim: buyrun.

Mənbələr:

[1] http://alicanakkus.com/2014/12/android-sqlite-1/
[2] https://gelecegiyazanlar.turkcell.com.tr/konu/android/egitim/android-401/veritabani-kullanimi
[3] http://umiitkose.com/2015/09/android-studio-sqlite-giris/http://umiitkose.com/2015/09/android-studio-sqlite-veritabani-olusturma/http://umiitkose.com/2015/09/android-sqlite-ekleme-guncelleme-silme-kayit-getirme/
[4] https://www.youtube.com/watch?v=CVN2vY7fmeo&t=173s

 

Android 38: ListView (7)

Və nəhayət gəldik çatdıq işin pik nöqtəsinə. Bu yazımızda biz İntent işlədərək yeni bir səhifə açıb həmin səhifədən data alacağıq. Aldığımız datanı listimizə ötürəcəyik.

İşi ən başından, yeni bir səhifə (activity) yaradaq.

Adını da qoyaq AddActivity.

Finish deyirik və gözləyirik arxafondakı proseslər tamamlansın.

Proseslər tamamlandı. Hər şey qaydasında. Daxil oluruq activity_add.xml-ə 3 EditText əlavə edirik, EditText-lərə id təyin edirik. Button əlavə edib id təyin edirik. Nəticə aşağıdakı kimi olacaq:

Qəstlə şəkil elədim ki, kodu kopyalaya bilməyəsiniz, özünüz əllə yazın, əliniz öyrəşsin.

Gəlirik MainActivity-yə. FloatingActionButton kliklənərkən ediləcək hissəyə gələk. Oranı silək və orda İntent yazaraq AddActivity-mizə keçid verək.

FloatingActionButton floatingActionButton = findViewById(R.id.addItem);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, AddActivity.class);
        startActivityForResult(intent, 1);
    }
})

AddActivity-nin içinə keçək indi. Əvvəl hər üç dəyişənimizi və buttonumuzu tanıdırıq. Sonra buttona klikləyərkən nələr baş verdiyini yazırıq. Bu hissəni sürətli keçəcəm çünki 3031-ci yazılarda necə etdiyimizi görmüsünüz.

Bilirsiz də nyə şəkil qoydum?

Dəvam edək. Qayıdırıq MainActivity-yə, onActivityResult hissəsin yazmağa. Aldğımız datanı ötürəcəyimiz yer hər üç data üçün olan dəyişənlərdir.

this.newName = data.getStringExtra("newName");
this.newSurname = data.getStringExtra("newSurname");
this.newClass = data.getStringExtra("newClass")

Adapterə aldığımız dəyişənləri ötürək, adapterimizi yeniləyək və görünüşü ən aşağı edək.

adapter.addItem(new Student(newName, newSurname, newClass));
adapter.notifyDataSetChanged();
listView.smoothScrollToPosition(adapter.getCount()-1);

Kiçik bir qeyd, adapterlə listview-i onCreate metodunun daxilində təyin etmişdik, onların başlanğıc nöqtəsin qaldırdıq yuxarı (onCreate metodu başlamadan olan hissəyə).

İndi tədbiqetməmizi işə salaq, və aşağıdakı nəticələri alaq.

Bu silsilədən də bu qədər. Kodları bu linkdən əldə edə bilərsiniz. Əvvəl özünüz yoxlamağa çalışın. İnanıram ki, alınacaq. Əgər hardasa ilişsəz, çətinliyiniz olsa kodlara baxa bilərsiniz. Yox izah etmə formam sizə çətin gəlirsə, məndən də yaxşı ziah edən türkcə/ingiliscə/rusca mənbələrə baxa bilərsiniz (baxın da, hətta bura qədər rahatlırla gəlmisinizsə belə yenə də kənar mənbələrə baxın, daha dərinləməsinə öyrənməyə çalışın.) Oxşar çoxlu tapşırıqlar etməyə çalışın. Alınacaq sizdə! Uğur ola!

Android 37: ListView (6)

Hər şey əla. İndi gəlin bir ədəd button əlavə edək. Hansı ki ona klikləyərkən yeni sətr əlavə olunsun.

Əvvəlcə main_activity.cml-ə keçid edirik. ListView-imizi bir RelativeLayout-un içinə qoyuruq.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" />
    
</RelativeLayout>

İndi aşağıda Design hissəsindən yuxarda Buttons-ların içində “FloatingActionButton” var, yükləyirik:

Yükləmə iconuna klikləyirik:

“OK” deyib yükləməyə başlayırıq.

Proses bitdikdən sonra “FloatActionButton”-ı sürükləyib ekrana atırıq (ListView-imiz görünən hissəyə, sağ aşağı küncə).

Qarşımıza belə bir pəncərə çıxır. Android-i seçib axtarış yerinə “add” yazırıq.

Add buttonunu seçib “OK” düyməsin basırıq.

Id-sini “addItem” olaraq dəyişək və yuxarıdakı kimi layout_margin əlavə edək.

<android.support.design.widget.FloatingActionButton
    android:id="@+id/addItem"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true"
    android:layout_alignParentRight="true"
    android:layout_margin="16dp"
    android:clickable="true"
    app:srcCompat="@android:drawable/ic_menu_add" />

İndi keçid edirik MainActivity-yə. Orada buttonumuzu təyin edək və id-sini mənimsədək. Ardınca setOnClick yazaq ki ona cliklənəndə arrayList-imizə yeni element artırılsın. ArrayList-in əvvəlinə final yazırıq.

FloatingActionButton floatingActionButton = findViewById(R.id.addItem);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) { 
    }
});

İndi keçid edirik Adapterə, orda AddItem metodu yaradırıq, Student tipində opyekt qəbul etsin və aldığı obyekti arrayList-ə add etsin deyə.

public void addItem(Student student){
    arrayList.add(student);
}

İndi isə floatingActionButton-un setOnClick olan hissəsinə qayıdıb içini dolduraq. (ArrayAdapter-i də final etmək yaddan çıxmasın)

dapter.addItem(new Student("YeniAd", "YeniSoyad", "0X"));

Və əlavə olaraq listView-i yeniləmək lazımdır. Bunun üçün də adapterin notifyDataSetChanges() metodunu çağırırıq.

adapter.notifyDataSetChanged();

Son olaraq da 1 sətr kod əlavə edək ki, listView bizə ən aşağını göstərsin. (Buna görə də ListView-ə də bir ədəd final əlavə edirik əvvəlinə.

listView.setSelection(adapter.getCount() - 1);

İndi tədbiqetməmizi işə salaq:


Belə. Biraz çətinə düşəsiz deyə kodalrı sizə vermirəm. Növbəti yazıda, silsilənin sonuncu yazısında verəcəm. Haydi bura qədər edin, keçək növbəti yazıya. Uğur ola!

Android 36: ListView (5)

İndi gələk əsas məsələlərə. Bu yazıda nə edəcəyik? list_item.xml faylımızın başına oyun gətirəcəyik. Bir ədəd Model yaradacağıq. Sonra da masivimizin üzərində dəyişiklik edəcəyik. Son olaraq da Adapterimizdə yeni view-larımızı yazmalıyıq.

İş çoxdu, vaxt itirməyək. Getdik!

İşə Model clası yaratmaqla başlayaq. (Baxın ha, mən adını Student qoydum. Siz istədiyinizi qoya bilərsiniz)

İndi həmin sinfə ad qoyaq.

Əla. Gözümüzün önünə siyahını gətirək. Siyahıda nəyimiz olacaq? Mənim siyahımda şagirdin adı, soyadı, sinif nömrəsi (misal üçün 8a, 9c). İndi həmin dəyişənləri modelimiz üçün təyin edək, kontruktorunu yaradaq, getter/setter-lərini yaradaq.

Private formada Stringlərimizi yaratdıq. İndi ekrana sağ klikləyirik, “Generate…” seçirik.

Əvvəl Constructoru seçirik,

Açılan pəncərədə hər üçünü də seçib “OK” deyirik.

İndi Generate-ə girib “Getter” seçirik (Setteri ona görə seçmədik ki, konstruktorumuz həmin setter funksiyasın yerinə yetirir onsuz).

Açılan pəncərədə hər üçünü də seçib “OK” vururuq.

Beləcə, modelimizi yaratmış olduq. Kodları aşağıdakı kimidir:

 package com.wordpress.muzefferpasazade.listview;

public class Student {
    private String studentName;
    private String studentSurname;
    private String studentClass;

    public Student(String studentName, String studentSurname, String studentClass) {
        this.studentName = studentName;
        this.studentSurname = studentSurname;
        this.studentClass = studentClass;
    }

    public String getStudentName() {
        return studentName;
    }

    public String getStudentSurname() {
        return studentSurname;
    }

    public String getStudentClass() {
        return studentClass;
    }

} 

İndi həmin modelimizə uyğun xml-imizin başına oyun açaq. Belə ki, RelativeLayout içərisində 3 TextView təyin edək, id-lərini verək və formasını özümüzə uyğun düzəldək.

</pre>
<pre><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="32dp">

    <TextView
        android:id="@+id/textName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Name"
        android:textColor="#000000"
        android:textSize="22sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textSurame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textName"
        android:text="Surname"
        android:textColor="#000000"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/textClass"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="9B"
        android:textSize="36sp"
        android:textStyle="bold" />

</RelativeLayout></pre>
<pre>

İndi qayıdırıq MainActivity-yə. Massivimizi dəyişirik. Artıq bizə o sərf etmir. Biz daha geniş, 1 indeksdə bir neçə element saxlaya biləcək bir listə ehtiyacımız var. “ArrayList<>”!

ArrayList yaradırıq, tipini isə öz modelimizə uyğun Student yazırıq.

ArrayList<Student> arrayList = new ArrayList<>();

arrayListimizə element əlavə edərkən .add() metodundan istifadə edirik. Gəlin bu metoddan istifadə edərək arrayList-imizi dolduraq:

<pre>ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(new Student("Müzəffər", "Paşazadə", "11b"));
arrayList.add(new Student("Anton", "Kanibolotsky", "10a"));
arrayList.add(new Student("Ibrahim", "Sehic", "9c"));
arrayList.add(new Student("Shakhruddin", "Makhammadaliev", "8d"));
arrayList.add(new Student("Jakub", "Rzezniczak", "7a"));
arrayList.add(new Student("Badavi", "Guseynov", "6b"));
arrayList.add(new Student("Elvin", "Yunuszade", "5a"));
arrayList.add(new Student("Maksim", "Medvedev", "4d"));
arrayList.add(new Student("Gara", "Garayev", "3c"));
arrayList.add(new Student("Ramil", "Sheydaev", "2b"));
arrayList.add(new Student("Joshgun", "Diniyev", "1a"));</pre>

(Qeyd: Adları buradan götürmüşəm)

Hə əla. İndi gedirik adapterimizə. Əvvəl ViewHolder-imizin içində digər dəyişənlər üçün də TextView əlavə edək:

<pre>public class ViewHolder {
    TextView textName;
    TextView textSurname;
    TextView textClass;
}</pre>
<pre>

Hə. Necə ki aşağıdakı sətr var idi ey:

viewHolder.textName = convertView.findViewById(R.id.textView);

Bax bunlar kimi digər iki dəyişənimiz üçün də yazaq (xml-dəki id-lərimizə uyğun):

viewHolder.textName = convertView.findViewById(R.id.textName);
viewHolder.textSurname = convertView.findViewById(R.id.textSurame);
viewHolder.textClass = convertView.findViewById(R.id.textClass);

İndi yuxarı qalxırıq. Bizə massiv gəlirdi ey, konstruktorun üzərində (Adapter sinfində) dəyişənlər var idi ey, o massivi dəyişib ArrayList etmək lazımdı axı.

İndi getCount və getİtem hissəsinə baxsaq qırmızılar görərik. Çünki massivi sildik axı, arrayListimizi həmin hissələrə uyğunlaşdıraq.

@Override
public int getCount() {
return arrayList.size();
}

@Override
public Student getItem(int position) {
return arrayList.get(position);
}

Qayıdırıq getView() metoduna. if-else blokundan sonra modelimizi (Student) təyin edirik getItem metodu ile position ötürüm həmin indeksdəki obyektini alırıq:

Student studen = getItem(position);

Orada aşağıda “viewHolder.textName.setText(name[position]);” var ey, onun setText-hissəsin dəyişib studen.getStudentName() edirəm, buna uyğun da digər iki dəyişəni yazıram.

viewHolder.textName.setText(studen.getStudentName());
viewHolder.textSurname.setText(studen.getStudentSurname());
viewHolder.textClass.setText(studen.getStudentClass());

Son kiçik bir dəyişiklik. MainActivity-ə keçid edib massivi silib, Adapterə yeni yaratdığımız arrayList-i göndərməyi unutmayaq:

Adapter adapter = new Adapter(MainActivity.this, arrayList);

Və nəticə:

Məncə artıq kodları sizə verə bilərəm. Buyrun.

Belə. Sizə çox çətin bir ev tapşırığı. Üzərinə klik etdikdə şagirdin adı yazılı olan Toast mesaj çıxsın.

Bu yazıdan da bu qədər. Uğur ola!

Android 35: ListView (4)

Bu yazımızda ad kiçik amma ciddi dəyişiklik edəcəyik. Nəticə etibari ilə yaddaşda müəyyən əlavə yer tutumasından və proseslər çoxluğunun azaldılamsına gətirib çıxaracaq. Bunun üçün ViewHolder istifadə edəcəyik.

Gələk Adapter sinfimizə. Düşürük ən aşağı, metodların sonunda bir ədəd public class yaradırıq. (Adını mən ViewHolder qoydum ama siz istəsəz öz adınızı qoyun). İçində isə sadəcə 1 dəyişən var. TextView textName.

public class ViewHolder{
TextView textName;
}

Qayıdırıq bir qədər yuxarı, getView() metodumuzun içinə.  Əvvəl ViewHolder-in obyektini yaradırıq. (ViewHolder viewHolder;), sona isə if-else bloku açırıq. Əgər converView ilk dəfə yaradılacaqsa (null-dursa) müəyyən prosesləri eləsin, yox təkrar yaradılacaqsa, yaratmasın, viewHolderimizdən istifadə eləsin. Belə deyim sizə: Normalda hər bir position (element sətri üçün) convertView yaradılır. Sonra ekranı biz aşağı sürüşdürdükdə, ekranın position-ına uyğun yeni  convertView yaradır. Geri, yuxarı sürüşdürdükdə köhnələri istufadə etmir, yenidən yaradırdı. Bax o təkrar eyni şeyi yaratmaması üçün ViewHolder-dən istifadə edəcəyik.

İfdən əvvəl boş bir viewHolder yaratmışdıq, əgər tədbiqetmə ilk dəfə açılırsa, nəticə etibari ilə convertView null olur, o zaman bizim də obyektimiz yeni olaraq yaradılmalıdır, if blokunun içidə ViewHolderimizi yaradaq:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView==null){
viewHolder = new ViewHolder();
}
return convertView;
}

Keçən yazıdakı converView-i indi yarada bilərik.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView==null){
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
TextView textView = convertView.findViewById(R.id.textView);
textView.setText(name[position]);
}
return convertView;
}

So əlavə etdiyimiz iki sətr bundan əvvəlki yazıda olan sətrlərdir. İndi ordakı “TextView textView ” var ha “convertView.findViewById(R.id.textView);” bərabər olan, onu dəyişib, viewHolder-dəki textName-ə mənimsədək. setText-i də viewHolder.textView-ə edək.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView==null){
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
viewHolder.textName = convertView.findViewById(R.id.textView);
viewHolder.textName.setText(name[position]);
}
return convertView;
}

İndi convertView üçün setTag metodundan istifadə edib yaratdığımız obyekti ötürəcəyik.

 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
ViewHolder viewHolder; 
if(convertView==null){ 
viewHolder = new ViewHolder(); 
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false); 
viewHolder.textName = convertView.findViewById(R.id.textView);
viewHolder.textName.setText(name[position]);
convertView.setTag(viewHolder);
} 
return convertView; 
} 

Bura qədər əla, indi keçəl else hissəsinə, yəni convertView-imiz null deyilsə, əvvəldən yaradılıbsa, yenidən yaradılmasın – əvəzində viewHolder-imiz convertView-d’n getTag() etdiyimizə bərabər olsun.

else{
viewHolder = (ViewHolder) convertView.getTag();
}

Kiçik bir dəyişiklik daha etməliyik. İf blokumuzdakı “viewHolder.textName.setText(name[position]);” var ha, bax onu ordan götürüb, aşağı, else bloku bitəndən sonra yazmalıyıq.

Son nəticəmiz aşağıdakı kimi olur:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;
    if(convertView==null){
        viewHolder = new ViewHolder();
        convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
        viewHolder.textName = convertView.findViewById(R.id.textView);
        convertView.setTag(viewHolder);
    }else{
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.textName.setText(name[position]);

    return convertView;
}

Bua ciddi hissədir, bir də başdan, təkrar gedin. Qarışdırıla bilər, çətin anlaşıla bilər. İzahatım xoşagələn deyilsə, başqa mənbələrə baxın. Mən isə öz növbəmdə hər ikisinin fərqini rahatlıqla görə bilməyiniz üçün şəkilləri əlavə edim:

Əvvəl:

Sonra:

Belə. Bu yazılıq da bu qədər. Növbəti yazımız yəqin ki, daha uzun olacaq. Ediləcək çox iş var. 2-3 textView əlavə etməliyik hər bir listView sətri üçün. Ona görə də bura qədər olan hissələri tam öyrəndiyinizə əmin olun. Uğur ola!

Android 34: ListView (3)

Yaxşı, ötən yazıda biz text-imizə müəyyən görünüş verdik. Bəs axı necə bunu sağa çəkəcəyik? Ya da ortada göstərək? Adapter-adapter deyirsiz, nədir axı bu adapter?

Gəlin bir adapter yaradaq, sonra list_itemin də üzərində biraz işləyək. Nəticə etibari ilə daha yaxşı bir görünüş əldə edək.

Əvvəlcə yeni Java Class yaradırıq.

 

Adını da “Adapter” qoyuruq.

İndi keçək kod hisəmizə. Biz əvvəl bu adapterə “BaseAdapter” sinifini extends etməliyik.

Fikir versəz görrəsiniz ki sinfinimizin adı olan sətrin altı qırmızı dalğalanıb. Mausu üstünə gətirəndə informasiya verir ki BaseAdapterin müəyyən metodları var ki həmin abstract metodları impliment etməliyik.

Bunun üçün də mausu həmin sətirdə sol klikləyirik, qırmızı rəngi lampa görürük, ona klikləyib aşağıdakını seçirik:

İmplement methods seçirik, aşağıdakı pəncərə açılır və biz “OK” deyirik.

Proseslər bitəndən sonra vəziyyət belə olacaq:

 

Bir String tipli name massivini, Context tipli context dəyişənini təyin edək və konstruktor metod yaradaq:

String[] name;
Context context;

public Adapter(Context context, String[] name){
    this.context = context;
    this.name = name;
}

İndi aşağıdakı metodalrı dolduraq. İlk əvvəl getCount. GetCount metodu listViewin neçə massiv daxil edəcəyindən asılı olaraq neçə massiv göstərəcəyini bildirir. Belə deyək, istifadəki ekranda listView daxilində neçə element görəcək. biz ona “name.length” verək (name massivimizin uzunluğunu).

GetItem metodu o an üçün (misal üçün listdə kliklənən hansı elemtdirsə onun yeri) – istifadə edilən elemntin yerini qaytarır. Bunun üçün “name[position]” yazırıq.

İndi əsas hissəyə keçək. getView metodunun içinə yazılmalı olanlardan. ConvertView-ə LayoutInflater-i mənimsədirəm, TextView-in id-sini tapıram. Yuxardakı name massivinin o ankı elementini bu textView-ə ötürürəm.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);

TextView textView = convertView.findViewById(R.id.textView);
textView.setText(name[position]);

return convertView;
}

MainActivity-də ediləsi kiçik bir xıra dəyişiklik qaldı. Adapterimiz var idi, onu silirik, yerinə yeni təyin etdiyimiz adapterə lazimi məlumatları ötürürük:

Adapter adapter = new Adapter(MainActivity.this, massiv);

List_item.xml faylızda textView üçün “android:gravity=”center”” əlavə etməyi unutmayaq.

Bu yazıda əvvəlkindən fərqli olaraq “ArrayAdapter”-i yox öz xüsusi (Custom Adapter) qruduğumuz Adapter-i istifadə etdik, xml-də də kiçik dəyişiklik edərək yazıları mərkəzə aldıq. Bəs sual yaranır ki, xüsusi adapter nə üçün lazımdı? İndi biz sadəcə 1 text-dən istifadə edirik, 2 yazı sonra eyni sətirdə bir neçə text-i birdən göstərəcəyik, o zaman indi hazırladığımız adapterdin üzərindən gedəcəyik.

Bura qədər hər üç yazıdakı kodaları özünüz etməyə çalışın. Ev tapşırığı verim, sarı rəngli textlərimizi sağa çəkin, screenləri gözləyirik. Uğur ola!