contoh notifyDataSetChanged

166

Saya mencoba untuk digunakan dalam saya Android Applicationyang notifyDataSetChanged()metode untuk ArrayAdaptertetapi tidak bekerja untuk saya.

Saya menemukan jawaban di sini , yang notifyDataSetChanged()seharusnya berjalan di utas utama, tetapi tidak ada contoh untuk itu.

Adakah yang bisa mengirim contoh atau setidaknya tautan?

Tima
sumber
Anda dapat memeriksa blog ini dan contoh ini di github dan ini juga
Cabezas

Jawaban:

328

Untuk ArrayAdapter, notifyDataSetChangedhanya bekerja jika Anda menggunakan add(), insert(), remove(), dan clear()pada Adapter.

Ketika sebuah ArrayAdapterdibangun, itu memegang referensi untuk Listyang disahkan. Jika Anda harus melewatinya Listyang merupakan anggota dari suatu Kegiatan, dan mengubah anggota Kegiatan itu nanti, ArrayAdapteria masih memegang referensi ke yang asli List. Adaptor tidak tahu Anda mengubah Listdalam Kegiatan.

Pilihan Anda adalah:

  1. Gunakan fungsi ArrayAdapteruntuk memodifikasi Daftar mendasari ( add(), insert(), remove(), clear(), dll)
  2. Buat kembali ArrayAdapterdengan Listdata baru . (Menggunakan banyak sumber daya dan pengumpulan sampah.)
  3. Buat kelas Anda sendiri yang berasal dari BaseAdapterdan ListAdapteryang memungkinkan perubahan Liststruktur data yang mendasarinya .
  4. Gunakan notifyDataSetChanged()setiap kali daftar diperbarui. Untuk menyebutnya di UI-Thread, gunakan runOnUiThread()dari Activity. Lalu, notifyDataSetChanged()akan berhasil.
jnosek
sumber
13
berhati-hatilah juga dalam menetapkan objek 'baru' ke data Anda. gunakan clear () sebagai gantinya, terisi kembali / buat perubahan pada data, lalu panggil notifyDataSetChanged ()
moonlightcheese
Tapi bagaimana kalau kita sebut notifyDataSetChanged()dengan cara seperti: ((BaseAdapter) arrayAdapter).notifyDataSetChanged();?
teoREtik
2
Saya menggunakan BaseExpandableListAdapter, ia tidak memiliki fungsi add () atau hapus () jadi saya menyimpan Peta saya sebagai variabel anggota. Saya memperbarui Peta dan memanggil notifyDatasetChanged () tetapi tidak ada yang terjadi. Ketika saya menggunakan pilihan # 4, itu berhasil. Mengapa???
emeraldhieu
Saya menggunakan ArrayAdapter untuk GridView kustom, saya menambahkan gambar saat saya mendapatkannya dari url dengan memanggil adapter.add (dataReceived). Ini berfungsi dengan baik menambahkan data tetapi mengapa itu menyegarkan & pergi ke atas. Saya ingin menampilkan item karena mereka akan mendapat tambahan tanpa daftar menyegarkan. (Apa yang ingin dilakukan adalah bekerja dengan GridView android menggunakan notifyDatasetChanged ()) Bagaimana saya bisa membuatnya berfungsi di customGridView (StaggeredGridView) ini.
MobileEvangelist
1
Saya mencoba membuat BaseAdapter saya sendiri untuk menambahkan metode penyortiran ke daftar, tetapi untuk beberapa alasan itu tidak akan berfungsi. Bukan berarti aplikasi saya lambat meskipun saya membuat ulang seluruh adaptor dengan daftar array yang diurutkan, tetapi masih membuat saya kesal. Bagaimana tepatnya itu akan menghasilkan banyak sampah? Saya berasumsi array sebenarnya dari data yang mahal disimpan sebagai referensi dalam aktivitas memanggil adaptor, artinya hanya adaptor yang akan dikumpulkan.
G_V
34

Anda dapat menggunakan runOnUiThread()metode ini sebagai berikut. Jika Anda tidak menggunakan ListActivity, sesuaikan kode untuk mendapatkan referensi ArrayAdapter.

final ArrayAdapter adapter = ((ArrayAdapter)getListAdapter());
runOnUiThread(new Runnable() {
    public void run() {
        adapter.notifyDataSetChanged();
    }
});
Brian
sumber
1
Saya mencoba menambahkan fragmen kode Anda dalam kode saya (Anda dapat menemukannya di sini stackoverflow.com/questions/3667442/how-to-refresh-adapter ) di metode onCreate, tapi saya masih belum berhasil :( Mungkin itu salah tempat untuk menambahkannya ?!
Tima
1
Pertanyaan Anda hanya bertanya bagaimana Anda bisa memanggil metode dan menjalankannya di utas UI utama. Ini menjawab pertanyaan itu. Dalam kasus khusus Anda ( stackoverflow.com/questions/3670500/… ) AsyncTask dan metode onPostExecute () tampaknya menjadi apa yang harus Anda pertimbangkan.
Brian
12

Baru-baru ini saya menulis tentang topik ini, meskipun posting ini sudah lama, saya pikir itu akan membantu seseorang yang ingin tahu bagaimana menerapkan BaseAdapter.notifyDataSetChanged()langkah demi langkah dan dengan cara yang benar.

Harap ikuti Bagaimana menerapkan dengan benar BaseAdapter.notifyDataSetChanged () di Android atau blog baru BaseAdapter.notifyDataSetChanged () .

Arif Nadeem
sumber
Hai saya mencoba contoh tautan pertama, tetapi alih-alih mItem.add(), saya hanya melakukan pengeditan satu elemen berarti seperti mItem.get(position).setImage(encodedImage)itulah mengapa itu memberikan kesalahan NullPointer pengecualian. hanya untuk add (), hapus (), hapus () dll
Shreekant N
notifyDataSetChanged akan bekerja untuk mengedit atau memodifikasi set data, pointer nol Anda adalah karena sesuatu yang lain, periksa log.
Arif Nadeem
7

Saya memiliki masalah yang sama dan saya memilih untuk tidak mengganti seluruh ArrayAdapter dengan instance baru secara terus menerus. Jadi saya meminta AdapterHelper melakukan pekerjaan berat di tempat lain.

Tambahkan ini di tempat Anda biasanya (mencoba) menelepon notifikasi

new AdapterHelper().update((ArrayAdapter)adapter, new ArrayList<Object>(yourArrayList));
adapter.notifyDataSetChanged();

Kelas AdapterHelper

public class AdapterHelper {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void update(ArrayAdapter arrayAdapter, ArrayList<Object> listOfObject){
        arrayAdapter.clear();
        for (Object object : listOfObject){
            arrayAdapter.add(object);
        }
    }
}
Kevin Parker
sumber
Saya memiliki beberapa ArrayAdapters lain dalam kode saya dan mereka telah bekerja tanpa masalah. Malam ini, saya memutuskan untuk mengubah SimpleCursorAdapter menjadi ArrayAdapter, dan itu TIDAK AKAN BEKERJA. Setelah berjuang dengan itu selama beberapa jam dan berusaha menemukan alasan mengapa itu tidak berhasil, saya menemukan kelas AdapterHelper Anda, dan SEKARANG ITU BEKERJA! Terima kasih!
proudgeekdad
1
Ini dapat dengan mudah dilakukan dalam suatu fungsi ... MENGAPA Anda akan membuat instance kelas baru untuk itu?
techiServices
2
Dalam fungsi Java disebut metode. Apa yang akan Anda usulkan, apakah metode yang dapat digunakan kembali ini di kelas yang sama dengan Array Adapter? Atau Fragmen / Aktivitas yang berisi tampilan daftar? Jadi ya, ini di kelas di mana ia dapat digunakan kembali. Jika Anda ingin membuatnya statis dengan segala cara, silakan.
Kevin Parker
1
Ide bagus. Yang lain akan memperluas ArrayAdapter, bernama ArrayAdapterCompat dan mengganti metode addAll (..), karena ini hanya tersedia sejak API 11. Di sana, periksa level API dan gunakan super.addAll(..)untuk API> 11 dan super.add (.. ) dalam kombinasi dengan iterasi seperti Anda: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { super.addAll(items); } else { for (Object o : collection) { super.add(o); } }. Sekarang cukup rentangkan dari kelas adaptor baru Anda.
Konsumierer
Sempurna! Terima kasih banyak @Kevin - ini persis yang saya butuhkan!
Kibi
3

Saya tahu ini adalah respons yang terlambat tetapi saya menghadapi masalah yang sama dan saya berhasil menyelesaikannya dengan menggunakan notifyDataSetChanged() di tempat yang tepat.

Jadi situasiku adalah sebagai berikut.

Saya harus memperbarui tampilan daftar di tab bilah tindakan (fragmen) dengan konten yang dikembalikan dari aktivitas yang sama sekali berbeda. Namun pada awalnya, listview tidak akan mencerminkan perubahan apa pun. Namun, ketika saya mengklik tab lain dan kemudian kembali ke tab yang diinginkan, tampilan daftar akan diperbarui dengan konten yang benar dari aktivitas lain. Jadi untuk menyelesaikan ini saya gunakannotifyDataSetChanged() adaptor action bar dalam kode aktivitas yang harus mengembalikan data.

Ini adalah cuplikan kode yang saya gunakan dalam aktivitas.

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) 
    {
        case R.id.action_new_forward:

            FragmentTab2.mListAdapter.notifyDataSetChanged();//this updates the adapter in my action bar tab
            Intent ina = new Intent(getApplicationContext(), MainActivity.class);
            ina.putExtra("stra", values1);
            startActivity(ina);// This is the code to start the parent activity of my action bar tab(fragment).
    }
}

Aktivitas ini akan mengembalikan beberapa data FragmentTab2dan secara langsung akan memperbarui tampilan daftar saya FragmentTab2.

Semoga seseorang menemukan ini berguna!

mutp
sumber