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>

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


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

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.


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);
    }
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.