notifyDataSetChanged örneği


166

Benim yönteminde kullanmaya çalışıyorum ama benim Android Applicationiçin çalışmıyor.notifyDataSetChanged()ArrayAdapter

Burada cevap olarak buldum , bu notifyDataSetChanged()ana iş parçacığında çalışması gerekir, ancak bunun için bir örnek yoktu.

Herkes bir örnek veya en azından bir bağlantı gönderebilir mi ?!



Bunu kontrol edebilirsiniz blog ve bu github örneğe ve de bu
Cabezas

Yanıtlar:


328

Bir için ArrayAdapter, notifyDataSetChangedkullandığınız takdirde çalışır add(), insert(), remove()ve clear()Adaptöründeki.

Bir yapıldığında, aktarılana ArrayAdapterilişkin referansı tutar List. Bir ListEtkinliğin üyesi olan bir etkinliğe geçecek ve daha sonra bu Etkinlik üyesini değiştirecek olursanız ArrayAdapter, orijinaline hala bir başvuru tutar List. Bağdaştırıcı List, Etkinlik'te değiştirdiğinizi bilmiyor .

Seçimleriniz:

  1. İşlevlerini kullanın ArrayAdapteryatan Listesini değiştirmek için ( add(), insert(), remove(), clear(), vb)
  2. ArrayAdapterYeni Listverilerle yeniden oluşturun . (Çok fazla kaynak ve çöp toplama kullanır.)
  3. Temel alınan veri yapısının değiştirilmesine izin veren BaseAdapterve kendi sınıfınızı oluşturun .ListAdapterList
  4. Kullanım notifyDataSetChanged()liste her güncellendiğinde. UI-İş parçacığında çağırmak için runOnUiThread()of Activity. Sonra notifyDataSetChanged()çalışacak.

13
verilerinize 'yeni' nesneler atamaya da dikkat edin. Bunun yerine clear () kullanın, verilerde yeniden doldurun / değişiklik yapın, ardından notifyDataSetChanged ()
moonlightcheese

Ama biz ne ararsanız notifyDataSetChanged()böyle bir şekilde: ((BaseAdapter) arrayAdapter).notifyDataSetChanged();?
teoREtik

2
BaseExpandableListAdapter kullanıyorum, add () veya remove () fonksiyonlarına sahip değil, bu yüzden Haritamı üye değişkeni olarak saklıyorum. Map'i güncelleyip notifyDatasetChanged () işlevini çağırıyorum ancak hiçbir şey olmuyor. # 4 seçeneğini kullandığımda işe yarıyor. Neden???
emeraldhieu

Ben özel GridView için ArrayAdapter kullanıyorum, ben adaptör.add (dataReceived) çağırarak onları urls almak gibi görüntüler ekliyorum. Bu iyi çalışır veri ekler ama neden canlandırıcı ve zirveye gidiyor. Listeyi yenilemeden ekleyecekleri gibi öğeleri göstermek istiyorum. (Ne yapmak istiyorum notifyDatasetChanged () kullanarak android GridView ile çalışmak) Nasıl bu customGridView (StaggeredGridView) çalışmasını sağlayabilir.
MobileEvangelist

1
Listeye sıralama yöntemleri eklemek için kendi BaseAdapter oluşturmayı denedim, ancak bazı nedenlerden dolayı işe yaramaz. Tüm bağdaştırıcıyı sıralı bir dizici ile yeniden oluştursam bile uygulamam yavaş değil, ama yine de beni rahatsız ediyor. Tam olarak nasıl çok fazla çöp yaratır? Gerçek maliyetli veri dizisinin, bağdaştırıcıyı çağıran aktivitede bir referans olarak tutulduğunu varsayıyorum, yani sadece bağdaştırıcı toplanacak.
G_V

34

runOnUiThread()Yöntemi aşağıdaki gibi kullanabilirsiniz . A kullanmıyorsanız ListActivity, kodunuzu referans almak için uyarlamanız yeterlidir ArrayAdapter.

final ArrayAdapter adapter = ((ArrayAdapter)getListAdapter());
runOnUiThread(new Runnable() {
    public void run() {
        adapter.notifyDataSetChanged();
    }
});

1
Ben (buradan bulabilirsiniz benim kodunda sizin kod parçası eklemek çalıştı stackoverflow.com/questions/3667442/how-to-refresh-adapter onCreate-yönteminde), ama yine de herhangi bir başarı yok :(
Eklemek

1
Sorunuz, yöntemi nasıl çağırabileceğinizi ve ana kullanıcı arayüzü iş parçacığında çalıştırabilmenizi istedi. Bu soruya cevap veriyor. Özel durumunuzda ( stackoverflow.com/questions/3670500/… ) AsyncTask ve onun onPostExecute () yöntemi göz önünde bulundurmanız gereken gibi görünüyor.
Brian

12

Geçenlerde bu konu hakkında yazdım, bu yazı eski olsa da, BaseAdapter.notifyDataSetChanged()adım adım ve doğru bir şekilde nasıl uygulanacağını bilmek isteyen biri için yararlı olacağını düşündüm .

Lütfen Android'de BaseAdapter.notifyDataSetChanged () veya daha yeni BaseAdapter.notifyDataSetChanged () blogunun doğru şekilde nasıl uygulanacağını takip edin .


Merhaba ben ilk bağlantı örneği denedim, ama bunun yerine mItem.add(), ben sadece bir öğe düzenleme yaptık yaptım mItem.get(position).setImage(encodedImage)neden NullPointer exeption hata veriyor gibi olabilir anlamına gelir. sadece add (), clear (), remove () etc için
Shreekant N

notifyDataSetChanged veri kümesini düzenlemek veya değiştirmek için çalışacaktır, boş işaretçiniz başka bir şeyden kaynaklanıyor, günlükleri kontrol edin.
Arif Nadeem

7

Aynı sorunu yaşadım ve tüm ArrayAdapter'ı sürekli yeni bir örnekle değiştirmemeyi tercih ediyorum. Böylece başka bir yerde ağır kaldırma yapmak AdapterHelper var.

Bunu normalde bildirim çağrısı yapacağınız yere ekleyin

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

AdapterHelper sınıfı

public class AdapterHelper {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void update(ArrayAdapter arrayAdapter, ArrayList<Object> listOfObject){
        arrayAdapter.clear();
        for (Object object : listOfObject){
            arrayAdapter.add(object);
        }
    }
}

Benim kodumda birkaç ArrayAdapters var ve onlar sorunsuz çalıştı. Bu gece, bir SimpleCursorAdapter bir ArrayAdapter dönüştürmeye karar verdi ve ÇALIŞMAYACAKTIR. Birkaç saat boyunca onunla mücadele ettikten ve neden işe yaramadığının bir nedenini bulmaya çalıştıktan sonra, AdapterHelper sınıfınızı buldum ve ŞİMDİ ÇALIŞIYOR! Teşekkürler!
proudgeekdad

1
Bu bir işlevde kolayca yapılabilir ... NEDEN bunun için yeni bir sınıf başlattınız?
techiServices

2
Java işlevlerinde yöntemler denir. Ne önerirsiniz, bu yeniden kullanılabilir yöntemin Dizi Bağdaştırıcısı ile aynı sınıfta olmasını ister misiniz? Veya liste görünümünü içeren Fragment / Activity? Yani evet, yeniden kullanılabileceği bir sınıfta. Elbette statik hale getirmek istiyorsanız devam edin.
Kevin Parker

1
İyi fikir. Bir diğeri, ArrayAdapterCompat adlı ArrayAdapter'ü genişletmek ve addAll (..) yöntemini geçersiz kılmaktır, çünkü bu yalnızca API 11'den beri mevcuttur. Orada API seviyesini kontrol edin ve super.addAll(..)API> 11 ve super.add (.. ) sizinki gibi yineleme ile birlikte: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { super.addAll(items); } else { for (Object o : collection) { super.add(o); } }. Şimdi sadece yeni adaptör sınıfınızı genişletin.
Konsumierer

Mükemmel! @Kevin çok teşekkürler - bu tam olarak ne gerekli oldu!
Kibi

3

Bunun geç bir yanıt olduğunu biliyorum ama benzer bir sorunla karşı karşıya kaldım notifyDataSetChanged()ve doğru yerde kullanarak çözmeyi başardım .

Benim durumum şöyleydi.

Tamamen farklı bir etkinlikten döndürülen içeriklerle bir eylem çubuğu sekmesindeki (fragman) bir liste görünümünü güncellemek zorunda kaldım. Bununla birlikte, başlangıçta liste görünümü hiçbir değişikliği yansıtmaz. Ancak, başka bir sekmeyi tıklayıp sonra istediğiniz sekmeye döndüğümde, liste görünümü diğer etkinlikten doğru içerikle güncellenir. Bunu çözmek notifyDataSetChanged()için veriyi döndürmek zorunda olan aktivitenin kodunda eylem çubuğu adaptörünü kullandım .

Bu, etkinlikte kullandığım kod snippet'idir.

@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).
    }
}

Bu etkinlik bazı verileri adresine döndürecek FragmentTab2ve doğrudan liste görünümümü güncelleyecek FragmentTab2.

Umarım birisi bunu faydalı bulur!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.