Android: Actualizar ListView en la primera actividad al regresar de la segunda actividad

Tengo un problema con la actualización de la lista cuando el usuario cierra una actividad y vuelve a la anterior. Veo que el problema es muy común pero no puedo solucionarlo.

He sobrepasado el método onResume:

@Override public void onResume() { super.onResume(); populateList(); } 

populateList () es un método donde lleno listView con lista de cadenas:

 arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item,list); listView.setAdapter(arrayAdapter); 

El problema es que cuando se cierra la segunda actividad, los nuevos elementos se agregan de nuevo en ListView, por lo que cada elemento se ha duplicado. Como si no estuviera actualizada.

Si pongo notifyDataSetChanged () en onResume () me lanza nullPointerException porque cuando se inicia la actividad por primera vez no hay adaptador inicializado cuando se inicia la actividad por primera vez.

No estoy seguro de cómo manejar esto.

 public class testActivity extends Activity { private int id=1; private ListView listView; private CustomArrayAdapter arrayAdapter; private ArrayList<String> list = new ArrayList<String>(); ArrayList<Item> objectList = new ArrayList<Item>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); } @Override public void onResume() { super.onResume(); populateList(); } private void populateList() { try { objectList = new GetAsyncTask(id).execute(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TimeoutException e) { // TODO Auto-generated catch block e.printStackTrace(); } int size = objectList.size(); String name; for (int i = 0; i < size; i++) { name = objectList.get(i).getName(); list.add(name); } arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item, list); listView.setAdapter(arrayAdapter); } } 

4 Solutions collect form web for “Android: Actualizar ListView en la primera actividad al regresar de la segunda actividad”

pozo derecho del palo, usted podría golpear fácilmente esto lejos con una declaración condicional simple que realice el comando solamente si el adaptador no es null :

  if (adapter != null) { adapter.notifyDataSetChanged(); } 

Pero esto me parece que, a un nivel más profundo, su código podría ser re-factorizado de alguna manera para ser más eficiente, aunque no necesariamente más funcional.


Hazlo asi:

 private int id = 1; private ListView listView; private CustomArrayAdapter arrayAdapter; private ArrayList<String> list = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); } @Override public void onResume() { super.onResume(); populateList(); } private void populateList() { ArrayList<Item> objectList; try { objectList = new GetAsyncTask(id).execute(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); } list.clear(); for (int i = 0; i <objectList.size(); i++) { String name = objectList.get(i).getName(); list.add(name); } if (arrayAdapter == null) { arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item, list); listView.setAdapter(arrayAdapter); } else { arrayAdapter.notifyDataSetChanged(); } } 

Cojo la lista de archivos desde el dispositivo y lo pongo en una lista en populateList (). Luego aplico el adaptador. Al volver esa lista en el dispositivo se cambia por lo que de nuevo hace lo mismo y ponerlo en una lista. El problema es que en ListView todavía hay elementos antiguos y nuevos elementos se agregan al final. Así que está duplicado.

Un enfoque básico es llamar a list.clear() antes de agregar los nuevos datos. Esto debería borrar los datos antiguos y evitar duplicados. (Pero es difícil proporcionar una respuesta exacta sin ver el código en cuestión …)


Adición
Debe agregar este código a su método onPostExecute() dentro de GetAsyncTask :

 int size = objectList.size(); String name; list.clear(); // or list = new ArrayList<String>(); for (int i = 0; i < size; i++) { name = objectList.get(i).getName(); list.add(name); } arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item, list); listView.setAdapter(arrayAdapter); 

A menos que GetAsyncTask esté anidado en su actividad, necesitará mover algunas variables a GetAsyncTask . Sin embargo, este enfoque es mejor porque no obliga a la Actividad a esperar resultados (lo que podría provocar un error "Aplicación no responde").

Sólo está mostrando parte del código de la aplicación, por lo que puede ser offbase aquí, pero supongo que está utilizando un cursor para devolver la list variables y utilizar la list para crear un ArrayAdapter …

Si desea que los datos sean "frescos", ¿por qué no utilizar un CursorLoader con LoaderManager? Hay varios beneficios para el LoaderManager (como mover la consulta fuera del hilo de la interfaz de usuario), y el LoaderManager hace un poco de trabajo pesado para usted cuando se trata de monitorear el DB para los cambios.

Hay una entrada en el blog que he encontrado bastante útil – http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html

Esto es todo suponiendo que está tirando de los datos de una base de datos …

El problema es que está llamando a la función populateList () sin borrar la lista primero. De esta forma, la lista de poblados simplemente agrega al contenido anterior.

Esta sería una manera correcta:

 public void onResume() { super.onResume(); list = new ArrayList<String>(); populateList(); } 

También no estoy seguro de por qué ha configurado el adaptador dentro de la función populateList()

Usted debe intentar esto.

  private ArrayList<String> list = new ArrayList<String>(); private ArrayList<String> populateList() { try { objectList = new GetAsyncTask(id).execute(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TimeoutException e) { // TODO Auto-generated catch block e.printStackTrace(); } int size = objectList.size(); String name; for (int i = 0; i < size; i++) { name = objectList.get(i).getName(); list.add(name); } return list; } arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item, populateList()); listView.setAdapter(arrayAdapter); 

Esa manera por tener el adaptador hacia fuera usted puede tener simplemente esto en la función del onResume ()

 public void onResume() { super.onResume(); list = new ArrayList<String>(); } 
  • ¿Se llama al método onResume después de que una alerta se descarta en Android?
  • ¿Por qué onResume se llama cuando abro por primera vez la pestaña de un tabhost?
  • Get onPause & onResume como eventos en el nivel de aplicación / tarea
  • Android: "Nivel de aplicación" Pausa y reanudar
  • Fragmento onResume () & onPause () no se llama en backstack
  • OnRestart () que se llama cuando se pulsa botón de nuevo, de alguna manera para evitar esto?
  • OnResume Cámara Reinit Negro Pantalla
  • Android ViewPager setCurrentItem no funciona después de onResume
  • ¿Cómo usar onResume ()?
  • La aplicación se bloquea cuando se reanuda
  • usando onResume y onPause
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.