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

Me reemplazado método onResume:

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

populateList() es un método donde puedo llenar el listView con la lista de Cadenas:

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

El problema es que cuando la segunda actividad está cerrado, los nuevos elementos se acaba de agregar de nuevo en el ListView, así que tengo cada elemento duplicado. Como que no se actualizan.

Si pongo notifyDataSetChanged() en onResume() me arroja nullPointerException porque cuando la actividad se inicia la primera vez no hay ningún adaptador de inicializan cuando la actividad es la primera vez que comenzó.

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);
    }
}
  • Mantener a un miembro de la variable que controla si el ListView ya contienen cadenas. Si es así, no llame a populateList().
  • El problema es con list, ¿cómo estás pueblan este?
  • Pero tengo que llamar a populateList() incluso si ListView contiene cadenas. Estoy tratando de actualizarlo. No estoy seguro si he entendido bien.
  • Ah, lo siento, no he entendido. Yo desactive el adaptador y, a continuación, añadir las cadenas de nuevo.
  • Cojo el list_of_files de dispositivo y la puso en una lista en populateList(). Entonces aplico adaptador. Sobre el retorno de esa lista en el dispositivo es cambiado por lo que de nuevo hace lo mismo y lo puso en una lista. El problema está en la vista de lista todavía hay elementos antiguos y nuevos elementos se acaba de agregar al final. Así que es un duplicado.
InformationsquelleAutor Cristiano | 2013-01-09

4 Comentarios

  1. 5

    bien a la derecha del palo, usted podría fácilmente golpear a esta distancia con una simple instrucción condicional que realiza el comando sólo si el adaptador no null:

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

    Pero esto me parece, en un nivel más profundo, el código podría ser re-compremos algo para ser más eficiente, aunque no necesariamente más funcional.


    hacerlo así:

    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();            
        }
    }
    • Lo puse así y ahora es el nuevo trabajo, pero todavía hay un problema con elementos duplicados. Por ejemplo, he de 5 elementos, el cambio de uno en segunda actividad y en la vuelta hay de nuevo esos viejos cinco en la lista, 1 (uno cambió en la segunda actividad) y 4 viejos que están duplicados. Como este si la última es editado: a, b, c, d, e, a, b, c, d, z
    • usted no ha puesto casi el código suficiente para nosotros para ayudar a usted lo suficiente. pero es necesario comprobar que cualquier bloque de código se está inicializando el list colección no es de ser llamado de nuevo, presumiblemente onResume El hecho de que usted necesita lo que me han sugerido que me tiene preocupado de que las cosas no son todo lo que podría ser.
    • Puedo poner un código antes de ediciones.
    • Funciona! Sólo una corrección. En la última else, a continuación arrayAdapter.notifyDataSetChanged(); también debe ser: arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item, list); listView.setAdapter(arrayAdapter); Si no, ListView contiene sólo los datos antiguos.
  2. 2

    Cojo el list_of_files de dispositivo y la puso en una lista en populateList(). Entonces aplico adaptador. Sobre el retorno de esa lista en el dispositivo es cambiado por lo que de nuevo hace lo mismo y lo puso en una lista. El problema está en la vista de lista todavía hay elementos antiguos y nuevos elementos se acaba de agregar al final. Así que es un duplicado.

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


    Además

    Usted debe agregar este código a tu onPostExecute() método 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);

    Menos GetAsyncTask está anidado en su Actividad, tendrá que mover un par de variables para GetAsyncTask uso de este. Pero este enfoque es mejor, porque no obliga a la realización de la Actividad esperar para resultados (lo que podría provocar una «Aplicación No Responde» error.)

    • Puedo poner un código antes de ediciones.
    • He actualizado mi respuesta.
    • Gracias por los consejos para AsyncTask! Yo le di a uno 🙂
  3. 0

    Que sólo se muestra parte del código de la aplicación, así que puede ser offbase aquí, pero supongo que usted está usando un Cursor para devolver el list variable y el uso de list para crear un ArrayAdapter…

    Si desea que los datos a ser «fresca», ¿por qué no utilizar un CursorLoader con el LoaderManager? Hay varios beneficios a la LoaderManager (como mover la consulta de el subproceso de interfaz de usuario), y el LoaderManager hace un poco de el trabajo pesado por usted cuando se refiere a la supervisión de la DB para los cambios.

    Hay un post en el blog que he encontrado muy útiles http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html

    Todo esto es suponiendo que usted está tirando de los datos de una base de datos…

  4. 0

    El problema es que se llama a la función populateList() sin borrar la lista en primer lugar. Que manera de rellenar la lista, simplemente se añade a la anterior contenido.

    Esta sería una manera correcta :

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

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

    Usted debe tratar de 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);

    Que manera de tener el adaptador puede tener simplemente esta en la onResume() función

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

Dejar respuesta

Please enter your comment!
Please enter your name here