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


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();

3

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

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


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);
    }
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.