2010-11-16 5 views
89

Cuando se modifican los datos asociados con el adaptador de matriz, ¿invalidar la vista de lista es suficiente para mostrar los valores actualizados? La siguiente pieza de código no funciona, ¿he entendido mal algo aquí?Actualizar la vista de lista cuando cambian los datos del adaptador

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

disposición usada:

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

Respuesta

149

sustituto:

mMyListView.invalidate(); 

para:

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

Si esto no funciona, consulte este hilo: Android List view refresh

+0

@blindstuff si tengo que actualizar el elemento único de la vista de lista a continuación, lo que tengo que hacer – Developer

+0

Si no existe BaseAdapter, notifyDataSetChanged() no se mostrará, por lo que necesita cambiar 'BaseAdapter 'to' YourCustomAdapter' –

7

cambiar esta línea:

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

a:

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

y después de la actualización del valor de un elemento de la lista, llame al:

adapter.notifyDataSetChanged(); 
4

invalidate(); llama a la vista de lista para invalidar sí mismo (es decir. color de fondo)
invalidateViews(); llama a todos sus hijos a ser invalidados. lo que le permite actualizar las vistas de los niños

Supongo que es un tipo de eficiencia que evita que todos los elementos constantemente tengan que volver a dibujarse si no es necesario.

1

Encontré una solución que es más eficiente que la respuesta actualmente aceptada, porque la respuesta actual obliga a actualizar todos los elementos de la lista. Mi solución actualizará solo un elemento (que fue tocado) llamando a los adaptadores getView y reciclando la vista actual, lo que agrega aún más eficiencia.

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

Cuestiones relacionadas