Aktualizowanie widoku listy po zmianie danych adaptera

104

Gdy dane powiązane z adapterem macierzy ulegną zmianie, unieważnienie widoku listy wystarczy, aby wyświetlić zaktualizowane wartości? Poniższy fragment kodu nie działa, czy coś tu źle zrozumiałem.?

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

Używany układ:

<?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>
Jasne
źródło

Odpowiedzi:

172

zastąpić:

mMyListView.invalidate();

dla:

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

Jeśli to nie zadziała, zapoznaj się z tym wątkiem: Odśwież widok listy Androida

ślepy
źródło
@blindstuff, jeśli muszę zaktualizować pojedynczy element widoku listy, to co muszę zrobić
Deweloper
Jeśli BaseAdapter nie istnieje, notifyDataSetChanged () nie pojawi się, więc musisz zmienić BaseAdapternaYourCustomAdapter
Junior Mayhé
12

Zmień tę linię:

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

do:

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

i po zaktualizowaniu wartości elementu listy wywołaj:

adapter.notifyDataSetChanged();
ritesh4326
źródło
3

invalidate();wywołuje widok listy, aby unieważnić siebie (tj. kolor tła),
invalidateViews();wywołuje unieważnienie wszystkich swoich dzieci. umożliwiając aktualizację widoków dzieci

Zakładam, że jest to jakiś rodzaj wydajności, który zapobiega ciągłemu przerysowywaniu wszystkich elementów, jeśli nie jest to konieczne.

user3044482
źródło
2

Znalazłem rozwiązanie, które jest wydajniejsze niż obecnie akceptowana odpowiedź, ponieważ aktualna odpowiedź wymusza odświeżenie wszystkich elementów listy. Moje rozwiązanie odświeży tylko jeden element (który został dotknięty), wywołując adaptery getView i odtwarzając bieżący widok, co zapewnia jeszcze większą wydajność.

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);
    }
});
Ignas
źródło