Actualización de la vista de lista cuando cambian los datos del adaptador

104

Cuando se cambian los datos asociados con el adaptador de matriz, ¿invalidar la vista de lista es suficiente para mostrar los valores actualizados? El siguiente fragmento de código no funciona, ¿entendí mal algo aquí?

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

Diseño utilizado:

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

Respuestas:

172

sustituir:

mMyListView.invalidate();

para:

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

Si eso no funciona, consulte este hilo: Actualización de la vista de lista de Android

ciego
fuente
@blindstuff si tengo que actualizar el elemento único de la vista de lista, entonces lo que tengo que hacer
Desarrollador
Si BaseAdapter no existe, notifyDataSetChanged () no aparecerá, por lo que debe cambiar BaseAdapteraYourCustomAdapter
Junior Mayhé
12

Cambie 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 actualizar el valor de un elemento de la lista, llame a:

adapter.notifyDataSetChanged();
ritesh4326
fuente
3

invalidate();llama a la vista de lista para invalidarse a sí misma (es decir, color de fondo)
invalidateViews();llama a todos sus hijos a invalidar. permitiéndole actualizar las vistas de los niños

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

usuario3044482
fuente
2

Encontré una solución que es más eficiente que la respuesta aceptada actualmente, porque la respuesta actual obliga a actualizar todos los elementos de la lista. Mi solución actualizará solo un elemento (que se tocó) 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);
    }
});
Ignas
fuente