Bagaimana cara kerja metode getView () saat membuat adaptor kustom Anda sendiri?

101

Pertanyaan saya adalah:

  1. Apa sebenarnya fungsi dari LayoutInflater?
  2. Mengapa semua artikel yang saya baca memeriksa apakah convertview nol atau tidak pertama? Apa artinya jika nol dan apa artinya jika tidak?
  3. Apa parameter induk yang diterima metode ini?
GrowinMan
sumber

Jawaban:

115

1: LayoutInflaterMengambil layout file XML Anda dan membuat objek View yang berbeda dari isinya.

2: Adaptor dibuat untuk menggunakan kembali Tampilan, saat Tampilan di-scroll sehingga tidak lagi terlihat, ini dapat digunakan untuk salah satu Tampilan baru yang muncul. Tampilan yang digunakan kembali ini adalah convertView. Jika ini null, artinya tidak ada Tampilan daur ulang dan kita harus membuat yang baru, jika tidak kita harus menggunakannya untuk menghindari pembuatan yang baru.

3: parentDisediakan sehingga Anda dapat memekarkan tampilan Anda ke dalam parameter tata letak yang tepat.

Semua ini bersama-sama dapat digunakan untuk secara efektif membuat tampilan yang akan muncul di daftar Anda (atau tampilan lain yang menggunakan adaptor):

public View getView(int position, @Nullable View convertView, ViewGroup parent){
    if (convertView == null) {
        //We must create a View:
        convertView = inflater.inflate(R.layout.my_list_item, parent, false);
    }
    //Here we can do changes to the convertView, such as set a text on a TextView 
    //or an image on an ImageView.
    return convertView;
}

Perhatikan penggunaan LayoutInflater, yang parentdapat digunakan sebagai argumen untuk itu, dan bagaimana convertViewdigunakan kembali.

Jave
sumber
5
Convertview == null berguna jika semua itens Anda mengikuti tata letak yang sama. Saat Anda perlu memeriksa radio atau tombol centang misalnya, dan mengubah tata letak berdasarkan setiap item, Anda perlu memflate ulang, atau mendapatkan tampilan cache.
sagits
Tidak perlu terlalu mengembang. Anda hanya perlu menulis switch atau if-else ladder di getview dan memekarkan tampilan sesuai dengan kasus Anda, timpa public int getItemViewType (int position) dan public int getViewTypeCount (). @sagits
Prashanth Debbadwar
Jika pernyataan biasanya berfungsi, tetapi saat menggunakan tombol radio, edit teks dan hal-hal semacam ini saya mengalami masalah saat menggunakan tampilan cache, ada beberapa pertanyaan mengenai hal ini di stack overflow.
sagits
71

getView()Metode di Adapter untuk tampilan menghasilkan item dari ListView, Gallery, ...

  1. LayoutInflaterdigunakan untuk mendapatkan View objek yang Anda menentukan dalam xml layout (objek akar, biasanya LinearLayout, FrameLayoutatau RelativeLayout)

  2. convertViewuntuk didaur ulang. Misalkan Anda memiliki tampilan daftar yang hanya dapat menampilkan 10 item dalam satu waktu, dan saat ini menampilkan item 1 -> item 10. Saat Anda menggulir ke bawah satu item, item 1 akan keluar dari layar, dan item 11 akan ditampilkan . Untuk menghasilkan View untuk item 11, metode getView () akan dipanggil, dan convertViewberikut adalah tampilan dari item 1 (yang tidak diperlukan lagi). Jadi, alih-alih buat objek View baru untuk item 11 (yang mahal), mengapa tidak menggunakan kembali convertView? => kita hanya memeriksa convertViewnull atau tidak, jika null buat tampilan baru, jika tidak gunakan kembali convertView.

  3. parentViewadalah ListView atau Galeri ... yang berisi tampilan item yang getView()dihasilkan.

Catatan : Anda tidak memanggil metode ini secara langsung, hanya perlu mengimplementasikannya untuk memberi tahu tampilan induk cara menghasilkan tampilan item.

Anh Tuan
sumber
2
PENJELASAN SANGAT BAIK untuk parentView, tidak dapat menemukan penjelasan yang lebih baik dari yang ini, +1
Ahmed Adel Ismail
Penjelasan yang luar biasa!
gabi
penjelasan bagus +1
tpk
8

Anda bisa melihat video ini tentang tampilan daftar. Ini dari tahun terakhir Google IO dan masih yang terbaik dalam pandangan daftar walk-through dalam pikiran saya.

http://www.youtube.com/watch?v=wDBM6wVEO70

  1. Ini mengembangkan layout (file xml di res / layout / folder Anda) menjadi Objek java seperti LinearLayout dan tampilan lainnya.

  2. Lihatlah videonya, akan membuat Anda up to date dengan apa gunanya tampilan convert, pada dasarnya ini adalah tampilan daur ulang yang menunggu untuk digunakan kembali oleh Anda, untuk menghindari membuat objek baru dan memperlambat pengguliran daftar Anda.

  3. Memungkinkan Anda untuk mereferensikan tampilan daftar Anda dari adaptor.

Ersman
sumber
5

Apa sebenarnya fungsi dari LayoutInflater?

Saat Anda mendesain menggunakan XML, semua elemen UI Anda hanyalah tag dan parameter. Sebelum Anda dapat menggunakan elemen UI ini, (misalnya TextView atau LinearLayout), Anda perlu membuat objek aktual yang sesuai dengan elemen xml ini. Itulah gunanya inflater. Inflater, menggunakan tag ini dan parameternya yang sesuai untuk membuat objek aktual dan menyetel semua parameter. Setelah ini, Anda bisa mendapatkan referensi ke elemen UI menggunakan findViewById ().

Mengapa semua artikel yang saya baca memeriksa apakah convertview nol atau tidak pertama? Apa artinya jika nol dan apa artinya jika tidak?

Yang satu ini menarik. Soalnya, getView () dipanggil setiap kali item dalam daftar ditarik. Sekarang, sebelum item bisa digambar, itu harus dibuat. Sekarang convertView pada dasarnya adalah tampilan yang terakhir digunakan untuk menggambar item. Dalam getView () Anda memekarkan xml terlebih dahulu, kemudian menggunakan findByViewID () untuk mendapatkan berbagai elemen UI dari listitem. Ketika kita memeriksa (convertView == null) yang kita lakukan adalah memeriksa bahwa jika tampilan adalah null (untuk item pertama) lalu membuatnya, jika tidak, jika sudah ada, gunakan kembali, tidak perlu melalui proses pemekaran lagi . Menjadikannya jauh lebih efisien.

Anda juga harus menemukan konsep ViewHolder di getView (). Ini membuat daftar lebih efisien. Yang kami lakukan adalah membuat viewholder dan menyimpan referensi ke semua elemen UI yang kami dapatkan setelah memekarkan. Dengan cara ini, kita bisa menghindari memanggil banyak findByViewId () dan menghemat banyak waktu. ViewHolder ini dibuat dalam kondisi (convertView == null) dan disimpan dalam convertView menggunakan setTag (). Di loop lain kita baru saja mendapatkannya kembali menggunakan getView () dan menggunakannya kembali.

Apa parameter induk yang diterima metode ini?

Induknya adalah ViewGroup tempat tampilan Anda dibuat oleh getView () akhirnya dilampirkan. Sekarang dalam kasus Anda ini adalah ListView.

Semoga ini membantu :)

Shubhayu
sumber
4
  1. Inflator tata letak memekarkan / menambahkan XML eksternal ke tampilan Anda saat ini.

  2. getView () dipanggil berkali-kali termasuk saat di-scroll. Jadi jika sudah ada view inflated kami tidak mau melakukannya lagi karena inflating adalah proses yang mahal .. oleh karena itu kami cek apakah nilainya null dan kemudian mengembang.

  3. Tampilan induk adalah sel tunggal dari Daftar Anda ..

ngesh
sumber
3
Pandangan orang tua salah dijelaskan di sini. Ini akan menjadi ListView bukan ListItem
Varun Jain
2

LayoutInflaterdigunakan untuk menghasilkan tampilan dinamis XML untuk ListViewitem atau dalam onCreateViewfragmen.

ConvertViewpada dasarnya digunakan untuk mendaur ulang tampilan yang saat ini tidak ada dalam tampilan. Katakanlah Anda memiliki scrollable ListView. Saat menggulir ke bawah atau atas, convertViewmemberikan tampilan yang digulir. Penggunaan kembali ini menghemat memori.

Parameter induk dari getView()metode ini memberikan referensi ke tata letak induk yang memiliki listView. Katakanlah Anda ingin mendapatkan Id dari item apa pun di XML induk, Anda dapat menggunakan:

ViewParent nv = parent.getParent();

while (nv != null) {

    if (View.class.isInstance(nv)) {
        final View button = ((View) nv).findViewById(R.id.remove);
        if (button != null) {
            // FOUND IT!
            // do something, then break;
            button.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Log.d("Remove", "Remove clicked");

                    ((Button) button).setText("Hi");
                }
            });
        }
        break;
    }

 }
pengguna936414
sumber
1

getView()metode buat baru Viewatau ViewGroupuntuk setiap baris Listviewatau Spinner. Anda dapat mendefinisikan ini Viewatau ViewGroupdalam Layout XMLfile di res/layoutfolder dan dapat memberikan referensi ke objek Adapterkelas.

jika Anda memiliki 4 item dalam Array yang diteruskan ke Adapter. getView()Metode akan membuat 4 View untuk 4 baris Adaper.

Kelas LayoutInflater memiliki Metode inflate () yang membuat Objek Tampilan dari layout sumber daya XML.

Ravi1187342
sumber
0

Anda juga dapat menemukan informasi berguna tentang getView di antarmuka Adapter di file Adapter.java. Ia mengatakan;

/**
 * Get a View that displays the data at the specified position in the data set. You can either
 * create a View manually or inflate it from an XML layout file. When the View is inflated, the
 * parent View (GridView, ListView...) will apply default layout parameters unless you use
 * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
 * to specify a root view and to prevent attachment to the root.
 * 
 * @param position The position of the item within the adapter's data set of the item whose view
 *        we want.
 * @param convertView The old view to reuse, if possible. Note: You should check that this view
 *        is non-null and of an appropriate type before using. If it is not possible to convert
 *        this view to display the correct data, this method can create a new view.
 *        Heterogeneous lists can specify their number of view types, so that this View is
 *        always of the right type (see {@link #getViewTypeCount()} and
 *        {@link #getItemViewType(int)}).
 * @param parent The parent that this view will eventually be attached to
 * @return A View corresponding to the data at the specified position.
 */
View getView(int position, View convertView, ViewGroup parent);
Hamza Polat
sumber