Mise à jour de la vue de liste lorsque les données de l'adaptateur changent


104

Lorsque les données associées à l'adaptateur de tableau sont modifiées, l'invalidation de la liste est suffisante pour afficher les valeurs mises à jour? Le morceau de code suivant ne fonctionne pas, ai-je mal compris quelque chose ici.?

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

Disposition utilisée:

<?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>

Réponses:


172

remplacer:

mMyListView.invalidate();

pour:

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

Si cela ne fonctionne pas, reportez-vous à ce fil: Actualisation de la vue Liste Android


@blindstuff si je dois mettre à jour l'élément unique de la liste, alors ce que je dois faire
Développeur

Si BaseAdapter n'existe pas, notifyDataSetChanged () n'apparaîtra pas, vous devez donc passer BaseAdapteràYourCustomAdapter
Junior Mayhé

12

Changez cette ligne:

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

et après avoir mis à jour la valeur d'un élément de liste, appelez:

adapter.notifyDataSetChanged();

3

invalidate();appelle la vue liste pour s'auto-invalider (c'est-à-dire la couleur d'arrière-plan)
invalidateViews();appelle tous ses enfants à invalider. vous permettant de mettre à jour les vues enfants

Je suppose que c'est une sorte d'efficacité qui empêche tous les éléments d'être constamment redessinés si ce n'est pas nécessaire.


2

J'ai trouvé une solution plus efficace que la réponse actuellement acceptée, car la réponse actuelle oblige tous les éléments de la liste à être actualisés. Ma solution actualisera un seul élément (qui a été touché) en appelant les adaptateurs getView et en recyclant la vue actuelle, ce qui ajoute encore plus d'efficacité.

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);
    }
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.