Обновление представления списка при изменении данных адаптера

104

Когда данные, связанные с адаптером массива, изменены, недействительности списка достаточно для отображения обновленных значений? Следующий фрагмент кода не работает, я что-то неправильно понял?

public class ZeroItemListActivity extends Activity {
    private ArrayList<String> listItems=new ArrayList<String>();
    private ListView mMyListView;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mMyListView=(ListView) findViewById(R.id.MyListView);
        mMyListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,listItems));
    }
    public void addItem(View v){
        listItems.add("list Item");
        mMyListView.invalidate();
    }
}

Используемая раскладка:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:text="@string/hello" />
    <ListView android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:id="@+id/MyListView"></ListView>
    <Button android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:id="@+id/AddItemsButton"
        android:text="Add Items" android:onClick="addItem"></Button>
</LinearLayout>
Суреш
источник

Ответы:

173

замена:

mMyListView.invalidate();

для:

((BaseAdapter) mMyListView.getAdapter()).notifyDataSetChanged(); 

Если это не сработает, обратитесь к этой теме: Обновление представления списка Android

слепой
источник
@blindstuff, если мне нужно обновить единственный элемент списка, то что мне нужно сделать
Разработчик
Если BaseAdapter не существует, notifyDataSetChanged () не будет отображаться, поэтому вам нужно изменить его BaseAdapterнаYourCustomAdapter
Junior Mayhé
12

Измените эту строку:

mMyListView.setAdapter(new ArrayAdapter<String>(this, 
                           android.R.layout.simple_list_item_1, 
                           listItems));

кому:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                                   android.R.layout.simple_list_item_1, 
                                   listItems)
mMyListView.setAdapter(adapter);

и после обновления значения элемента списка вызовите:

adapter.notifyDataSetChanged();
ritesh4326
источник
3

invalidate();вызывает представление списка для признания себя недействительным (т. е. цвет фона)
invalidateViews();вызывает недействительность всех его дочерних элементов. позволяя вам обновлять представления детей

Я предполагаю, что это какая-то эффективность, предотвращающая постоянную перерисовку всех элементов, если в этом нет необходимости.

user3044482
источник
2

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

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      // Edit object data that is represented in Viewat at list's "position"
      view = mAdapter.getView(position, view, parent);
    }
});
Игнас
источник