2010-11-16 4 views
89

Lorsque les données associées à l'adaptateur de matrice 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?Mise à jour de la vue de liste lorsque les données de l'adaptateur changent

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

Mise en page 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épondre

149

substitut:

mMyListView.invalidate(); 

pour:

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

Si cela ne fonctionne pas, reportez-vous à ce fil: Android List view refresh

+0

@blindstuff si je dois mettre à jour l'élément unique de la listview alors ce que je dois faire – Developer

+0

Si BaseAdapter n'existe pas, notifyDataSetChanged() ne sera pas affiché, vous devez donc changer 'BaseAdapter 'to' YourCustomAdapter' –

7

Modifier 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 la mise à jour de la valeur d'un élément de la liste, appelez:

adapter.notifyDataSetChanged(); 
4

invalidate(); appelle la vue de la liste d'invalider lui-même (ie. couleur d'arrière-plan)
invalidateViews(); appelle tous ses enfants à être invalidés. vous permettant de mettre à jour les vues des enfants

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

1

J'ai trouvé une solution plus efficace que la réponse actuellement acceptée, car la réponse actuelle force tous les éléments de la liste à être actualisés. Ma solution actualisera seulement un é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); } });

Questions connexes