getViewTypeCount dan metode getItemViewType dari ArrayAdapter

159

Dapatkah seseorang dengan kata-kata sederhana menjelaskan kepada saya penggunaan getViewTypeCount()dan getItemViewType()metode ArrayAdapter?

Eugene
sumber

Jawaban:

308

Ini menangani kasus di mana Anda ingin berbagai jenis tampilan untuk baris yang berbeda. Misalnya, dalam aplikasi kontak Anda mungkin ingin bahkan baris memiliki gambar di sisi kiri dan baris aneh memiliki gambar di sebelah kanan. Dalam hal ini, Anda akan menggunakan:

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
    return position % 2;
}

Kerangka kerja ini menggunakan jenis tampilan Anda untuk memutuskan tampilan mana yang akan Anda berikan convertViewdalam getViewmetode Anda . Dengan kata lain, dalam contoh di atas, baris genap Anda hanya akan mendapatkan tampilan daur ulang dengan gambar di sisi kiri untuk digunakan kembali, dan baris ganjil hanya akan mendapatkan gambar dengan gambar di sebelah kanan.

Jika setiap baris dalam daftar Anda memiliki tata letak yang sama, Anda tidak perlu khawatir tentang jenis tampilan. Bahkan, BaseAdapter.java menyediakan perilaku default untuk semua adaptor:

public int getItemViewType(int position) {
    return 0;
}

public int getViewTypeCount() {
    return 1;
}

Ini memang memberi Anda jenis tampilan yang sama untuk setiap baris.

Edit - untuk menguraikan alur umum:

  1. Anda mengikat data ke Anda AdapterViewmenggunakan adaptor.
  2. The AdapterViewmencoba untuk menampilkan item yang terlihat oleh pengguna.
  3. Kerangka kerja ini meminta getItemViewTypebaris n, baris yang akan ditampilkan.
  4. Kerangka kerja memeriksa kumpulan tampilan daur ulang untuk melihat jenis baris n. Tidak menemukan apa pun karena belum ada tampilan yang didaur ulang.
  5. getViewdipanggil untuk baris n.
  6. Anda meminta getItemViewTypebaris nuntuk menentukan jenis tampilan apa yang harus Anda gunakan.
  7. Anda menggunakan pernyataan if / switch untuk mengembang file xml berbeda tergantung pada jenis tampilan yang diperlukan.
  8. Anda mengisi tampilan dengan informasi.
  9. Anda mengembalikan tampilan, keluar getView, dan tampilan baris Anda ditampilkan kepada pengguna.

Sekarang, ketika tampilan didaur ulang dengan menggulir layar, masuk ke kolam tampilan daur ulang yang dikelola oleh kerangka kerja. Ini pada dasarnya diatur oleh tipe tampilan sehingga tampilan tipe yang benar diberikan kepada Anda dalam convertViewparameter dalam getViewmetode Anda :

  1. Kerangka kerja lagi panggilan getItemViewTypeuntuk baris yang ingin ditampilkan.
  2. Kali ini, ada pemandangan di kolam daur ulang dari jenis yang sesuai.
  3. Tampilan daur ulang diteruskan kepada Anda sebagai convertViewparameter untuk getViewmetode Anda .
  4. Anda mengisi tampilan daur ulang dengan informasi baru dan mengembalikannya.
Matthew Willis
sumber
1
@ Matius, terima kasih atas jawaban Anda. Bisakah Anda menggambarkan aliran bagaimana metode ini dipanggil. Saya juga tidak mengerti bagaimana ini sebenarnya terkait dengan data saya di res / layout.
Eugene
Tidak ada kontrak eksplisit untuk ketika metode ini dipanggil. res / layout adalah tempat untuk melihat objek. Ini adalah adaptor . Anda harus memeriksa jenis item dalam metode getView Anda dan mengembang tampilan yang tepat dari res / tata letak yang sesuai.
Matthew Willis
1
Anda mengembalikannya sendiri di getItemViewType.
Matthew Willis
Anda melakukan asosiasi secara manual di getView: if (ketik == 0) {/ * mengembang R.layout.row_icon_on_left /} else {/ mengembang R.layout.row_icon_on_right * /}
Matthew Willis
75
Awas! getItemViewType () harus mengembalikan int antara 0 dan getViewTypeCount () - 1.
PacificSky
12

Jika kita perlu menunjukkan berbagai jenis tampilan dalam tampilan-daftar maka itu baik untuk digunakan getViewTypeCount()dan getItemViewType()dalam adaptor daripada mengubah tampilan View.GONEdan View.VISIBLEbisa menjadi tugas getView()yang sangat mahal di dalam yang akan mempengaruhi daftar gulir.

Silakan periksa ini untuk penggunaan getViewTypeCount()dan getItemViewType()dalam Adaptor.

Tautan: the use-of-getviewtypecount

kyogs
sumber
Mengembalikan IGNORE_ITEM_VIEW_TYPE di getItemViewType () akan selalu memberikan 'view' sebagai null di getView (posisi int, View view, ViewGroup viewGroup) yang memaksa untuk menginisialisasi semua komponen UI. Bukankah itu indikator kinerja yang buruk di mana dalam kasus pola pemegang, kita dapat menggunakan kembali tampilan UI yang ada dan kita dapat dengan mudah beralih tampilan ke View.GONE atau View.VISIBLE berdasarkan posisi.
Namrata Bagerwal
11

Watch Outttt !!!!
Saya harus menghadapi masalah menerapkan ListViewkemarin dan itu dua jenis tampilan untuk baris mendapat campur aduk setelah saya gulir. Meskipun jawaban pilihan teratas dalam utas ini memberikan penjelasan umum yang baik, itu belum menyoroti sedikit informasi yang paling penting untuk menghentikan bug UI di atas yang telah saya sebutkan.

Berikut adalah penjelasan saya:
Kedua getViewTypeCount()dan getItemViewType()sedang digunakan oleh BaseAdapter's getViewmetode untuk mengetahui jenis pandangan harus itu mengambil, daur ulang dan kembali. (seperti yang dijelaskan dalam jawaban teratas di utas). Tetapi jika Anda tidak menerapkan kedua metode ini secara intuitif sesuai dengan Doc API Android, maka Anda mungkin masuk ke masalah yang saya sebutkan.

Diringkas Pedoman pelaksanaan:
Untuk menerapkan beberapa jenis Viewsuntuk ListView's baris kita harus dasarnya menerapkan, getItemViewType()dan getViewTypeCount()metode. Dan getItemViewType()dokumentasi memberi kami Catatan sebagai berikut:

Catatan: Integer harus dalam kisaran 0hingga getViewTypeCount() - 1. IGNORE_ITEM_VIEW_TYPEjuga bisa dikembalikan.

Jadi di Anda, getItemViewType()Anda harus mengembalikan nilai untuk Jenis Tampilan, mulai dari 0, ke jenis terakhir sebagai (jumlah jenis - 1). Misalnya, katakanlah Anda hanya memiliki tiga jenis tampilan? Jadi tergantung pada objek data untuk tampilan, Anda hanya bisa mengembalikan 0 atau 1 atau 2 dari getItemViewType()metode, seperti indeks array berbasis nol. Dan karena Anda memiliki tiga jenis tampilan yang digunakan, getViewTypeCount()metode Anda harus mengembalikan 3.

Dalam kasus apa pun jika Anda mengembalikan nilai integer lain seperti 1, 2, 3 atau 111, 222, 333 untuk metode ini, Anda pasti akan mengalami bug UI di atas yang baru saja Anda tempatkan dengan tidak mematuhi Android API Doc.

Jika Anda tidak mendapatkan petunjuk atau masih tidak dapat menyelesaikan dan memerlukan informasi lebih lanjut, baca jawaban terperinci saya dalam utas T&J StackOverflow ini .

Baca Dokumen Pengembang Android untuk informasi lebih lanjut Anda mungkin menemukan petunjuk secara langsung.

Semoga jawaban ini mungkin bermanfaat bagi seseorang di luar sana untuk menghemat banyak jam !!!

Bersulang!!!

Randika Vishman
sumber
1
Terima kasih telah menyebutkan bahwa IGNORE_ITEM_VIEW_TYPEsaya memiliki bug di salah satu ListView saya. Saya menggunakan ArrayAdapter untuk menyisipkan tampilan yang terdiri dari 1 gambar dan 2 tampilan teks. Saya hanya memiliki satu jenis tampilan. Saya mencoba untuk tidak menimpa metode getItemViewType, atau menimpanya dengan mengembalikan posisi atau integer hard-coded. Dalam semua kasus, saya mengalami duplikat dalam daftar saya, dengan perilaku aneh ketika menggulir (duplikat perubahan). Kembali IGNORE_ITEM_VIEW_TYPEdalam metode memperbaiki masalah. Terima kasih.
Alex
@Alex senang itu membantu Anda! :-)
Randika Vishman