Пример notifyDataSetChanged

Я пытаюсь использовать в методе Android Application notifyDataSetChanged() для ArrayAdapter для ArrayAdapter, но это не работает для меня.

Я нашел в качестве ответа здесь, что notifyDataSetChanged() должен запускаться в основном потоке, но для этого не было никакого примера.

Может ли кто-нибудь отправить пример или хотя бы ссылку?!

Ответ 1

Для ArrayAdapter, notifyDataSetChanged работает, только если вы используете add(), insert(), remove() и clear() в адаптере.

При построении ArrayAdapter он содержит ссылку для List, которая была передана. Если вы должны были передать в List, который был членом Activity, и позже измените этот член Activity, ArrayAdapter все еще держит ссылку на оригинал List. Адаптер не знает, что вы изменили List в Activity.

Ваши варианты:

  • Используйте функции ArrayAdapter для изменения базового списка (add(), insert(), remove(), clear() и т.д.)
  • Восстановите ArrayAdapter с новыми данными List. (Использует много ресурсов и сбор мусора.)
  • Создайте собственный класс, полученный из BaseAdapter и ListAdapter, который позволяет изменять базовую структуру данных List.
  • Используйте notifyDataSetChanged() каждый раз, когда список обновляется. Чтобы вызвать его в UI-Thread, используйте runOnUiThread() Activity. Тогда notifyDataSetChanged() будет работать.

Ответ 2

Вы можете использовать метод runOnUiThread() следующим образом. Если вы не используете ListActivity, просто адаптируйте код, чтобы получить ссылку на ваш ArrayAdapter.

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

Ответ 3

Недавно я написал на эту тему, хотя это сообщение старое, я подумал, что это будет полезно для тех, кто хочет знать, как реализовать BaseAdapter.notifyDataSetChanged() шаг за шагом и правильным способом.

Пожалуйста, следуйте Как правильно реализовать BaseAdapter.notifyDataSetChanged() в Android или новый блог BaseAdapter.notifyDataSetChanged().

Ответ 4

У меня была такая же проблема, и я предпочитаю не заменять весь ArrayAdapter новым экземпляром непрерывно. Таким образом, у меня AdapterHelper делает тяжелую работу где-то еще.

Добавьте это, где обычно (попробуйте) вызвать уведомление

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

Класс AdapterHelper

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

Ответ 5

Я знаю, что это поздний ответ, но я столкнулся с подобной проблемой, и мне удалось решить ее, используя notifyDataSetChanged() в нужном месте.

Итак, моя ситуация была следующей.

Мне пришлось обновить listview на вкладке панели действий (фрагмент) с содержимым, возвращенным из совершенно другой активности. Однако вначале список не отражал никаких изменений. Однако, когда я щелкнул еще одну вкладку и вернусь на нужную вкладку, список будет обновлен с правильным содержимым из другого действия. Чтобы решить эту проблему, я использовал notifyDataSetChanged() адаптера панели действий в коде действия, которое должно было вернуть данные.

Это фрагмент кода, который я использовал в этой операции.

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

Это действие вернет некоторые данные в FragmentTab2, и оно будет напрямую обновлять мой список в FragmentTab2.

Надеюсь, что кто-то найдет это полезным!