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>
Suresh
la source

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

aveugle
la source
@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();
ritesh4326
la source
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.

utilisateur3044482
la source
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);
    }
});
Ignas
la source