5

Tengo una aplicación en el mercado con un error que parece que no puedo resolver. Hoy lo he seguido hasta el siguiente método.ListView vacío a pesar de los elementos agregados al adaptador en algún momento al reanudar la aplicación

public void updateDealList(ArrayList<Deal> deals) { 
    // first call or showing bookmakrs (also gets called other times when adapter is null) 
    if (dealListAdapter == null || showingBookmarks || !dealListAdapter.moreDealsToDownload()) { 
     dealListAdapter = new EndlessDealListAdapter(getActivity(), 
       R.layout.deal_list_item, deals); 
     setListAdapter(dealListAdapter); 
     listView = getListView(); 
     if (getActivity().findViewById(R.id.right_fragment_container)!=null){ // if tablet 
      listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
      listView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT); 
     } 
     showingBookmarks=false; 
     Log.d("UPDATE_DEAL_LIST", "Notified list created new" + dealListAdapter.getCount()); 
     return; //PROBLEM OCCURS WHEN APP COMES IN HERE AFTER RESUMING 
    } 
    dealListAdapter.getDealListAdapter().clear(); 
    for (Deal d: deals){ 
     dealListAdapter.getDealListAdapter().add(d); 
     Log.d("UPDATE_DEAL_LIST", "added " + d.title); 
    } 
    dealListAdapter.notifyDataSetChanged(); 
    Log.d("UPDATE_DEAL_LIST", "Notified list " + dealListAdapter.getCount()); 
} 

Este método se pasa una matriz de objetos de negociación que se eliminan de Internet. Cuando se abre por primera vez la aplicación, los datos se extraen de Internet y se llama al método anterior, que crea un nuevo adaptador configurado para ListFragment. Este método también se llama cuando el usuario solicita más ofertas.

El problema que estoy teniendo es que la lista a veces piensa que está vacía a pesar del adaptador que contiene ofertas. Esto parece ocurrir cuando un uso reanuda la aplicación cuando su dispositivo tiene poca memoria (supongo que parte de la aplicación ha sido eliminada del RAM). Se llama a este método y dealListAdapter es nulo, por lo que se crea uno nuevo y se agregan ofertas. A pesar de esto, la lista permanece vacía y el usuario tiene que forzar el cierre de la aplicación para que funcione nuevamente.

La siguiente línea muestra tat cuando se llama el método ingresa el if y 21 ofertas se agregan al adaptador. Lamentablemente, la lista está vacía para el usuario.

05-23 01:52:32.879: D/UPDATE_DEAL_LIST(3478): Notified list created new21 
+0

Avíseme si hay algún código adicional que pueda ser útil. – bencallis

+0

Después de crear el adaptador, lo borra y agrega todas las entradas de la matriz de ofertas. ¿Cómo está almacenando esta matriz? Si es una variable miembro de la clase, no se conservará si el sistema mata tu actividad. ¿Guarda el estado de la actividad cuando está en pausa o detenido? http://developer.android.com/guide/topics/fundamentals/activities.html#SavingActivityState –

+0

Cuando está en el cuerpo if del método, vuelve al final para que el adaptador no se borre al instante. El adaptador se almacena como una variable de instancia en la clase ListFragment. ArrayList en sí mismo no se almacena, ya que cambia con frecuencia. Ningún estado está actualmente guardado. Parece que cuando la aplicación se inicia de nuevo después de ser asesinada se produce el problema. ¿Qué hace diferente a Android cuando relanza una aplicación después de que el sistema la mata, en lugar de iniciarla desde cero? – bencallis

Respuesta

0

Una idea (bastante largo tiro :)

Si la propia aplicación no murió , solo la actividad, el sistema intenta recrear el último estado de la actividad, llamando el onRestoreInstanceState(). Este método no se ejecutará si la aplicación se eliminó, por lo que esta es una de las grandes diferencias entre los dos.

ListActivity anula onRestoreInstanceState(). Asegura que la Lista existe antes de que continúe. Si la lista no existe, la infla desde el lugar predeterminado.

Si está configurando contentView en onResume() intente moverlo a onCreate(), eso puede resolver el problema.

Puedo ayudar más, si veo el código de la actividad.

0

Realmente no sé si esto va a ayudar o no, pero se supone que este método debe cambiar el tamaño de su lista en función de sus hijos. No entiendo por qué a veces notifyDataSetChanged() no funciona, la lista simplemente no cambia, pero usar esto en su lugar ha resuelto mi problema.

public static class Utility { 
    public static void setListViewHeightBasedOnChildren(ListView listView) { 
     ListAdapter listAdapter = listView.getAdapter(); 
     if (listAdapter == null) { 
      // pre-condition 
      return; 
     } 


     int totalHeight = 0; 
     int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST); 
     for (int i = 0; i < listAdapter.getCount(); i++) { 
      View listItem = listAdapter.getView(i, null, listView); 
      listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED); 
      totalHeight += listItem.getMeasuredHeight(); 
     } 

     ViewGroup.LayoutParams params = listView.getLayoutParams(); 
     int newHeight = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); 
     if (newHeight >= 100) 
      params.height = newHeight; 
     else 
      params.height = 100; 
     listView.setLayoutParams(params); 
     listView.requestLayout(); 
    } 
} 

Espero que ayude!

+0

Voy a intentar esto. ¿Simplemente llamo a esto en lugar de notifydatasetchange? – bencallis

+0

Sí, eso es lo que hice. Funcionó para mí No puedo encontrar de dónde saqué ese fragmento, no es mi trabajo. Había una buena explicación allí. – caiocpricci2

+0

http://stackoverflow.com/questions/3495890/how-can-i-put-a-listview-into-acrollview-without-it-collapsing/3495908#3495908 Esto parece serlo. Realmente no puedo ver por qué funcionaría ya que no estoy tratando de poner una vista de lista en una vista de desplazamiento. De todos modos lo intentaré e informaré de nuevo :) – bencallis

0

Usted puede tratar de una o más de las siguientes opciones

  • intente llamar setListShown(false) justo antes de ajustar el adaptador de la lista.

  • De lo contrario, haga
    setListShown(false);
    setListAdapter(null);

  • De lo contrario, hacer requestLayout()

Cuestiones relacionadas