Sólo en algunos teléfonos, ListView no se actualiza después de notifyDataSetChanged ()

Es weirded porque sucede solamente en algunos teléfonos que la resolución es FHD.

Cuando se muestra la interfaz de usuario, todo parece bien. Cuando hago clic en los elementos y llamar a notifyDataSetChanged (), el elemento no actualizará su aspecto. Necesito chascar encendido el ListView dondequiera otra vez, el artículo refrescará la disposición a la mirada correcta.

Si la vista de lista cambia de tamaño (ex: la función de búsqueda rediseñará toda la disposición), todo se convierte en OK.

Aquí está el código ListView:

public final class MyListView extends ListView implements AdapterView.OnItemClickListener { ArrayList<SELECT_ITEM> selectList; ArrayList<ID_ITEM> idList; ShowItemAdapter showAdapter; public MyListView(Context context) { selectList = new ArrayList<SELECT_ITEM>(); idList = new ArrayList<ID_ITEM>(); readIdList(mIdList); showAdapter = new ShowItemAdapter(context, idList, selectList); setAdapter(showAdapter); ... } @Override protected void onFinishInflate() { setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long ID) { boolean itemIsSelected = true; int size = selectList.size(); // remove if click item in selectList for(int i=0 ; i<size ; i++) { int selectID = selectList.get(i).id; if (idList.get(position).id == selectID) { itemIsSelected = false; selectList.remove(i); showAdapter.notifyDataSetChanged(); break; } } if (itemIsSelected) { SELECT_ITEM item = new SELECT_ITEM(); item.id = idList.get(position); selectList.add(item); // Here showAdapter.notifyDataSetChanged(); } ... } .... } 

Y aquí está el código del adaptador,

  public final class ShowItemAdapter extends BaseAdapter{ public ArrayList<ID_ITEM> mIdList; public ArrayList<SELECT_ITEM> mSelectList; public ShowItemAdapter(Context context, ArrayList<ID_ITEM> idList, ArrayList<SELECT_ITEM> selectList) { mIdList = idList; mSelectList = selectList; } @Override public int getCount() { int ret = mIdList.size(); return ret; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ... for(int i=0 ; i<size ; i++) { // is selected if (mIdList.get(position).id == selectList.get(i).id) { mIsSelected = true; break; } } if (mIsSelected) { textView.setBackgroundColor(Color.red); } else { textView.setBackgroundColor(Color.white); } } } 

¿Alguien me da una mano?

He encontrado que los teléfonos funcionan correctamente causará el mismo problema al depurar la pausa en getView (). Creo que .. es como "Views se ha actualizado por lo que no actualizar las vistas." Sin embargo, las vistas de actualización durante la depuración hacen que el ui no actualizar en realidad, entonces funciona de manera incorrecta.

Supongo que esto es sobre refrescantes vistas.

Veo un posible conflicto de código y un problema de tiempo entre getView () del adaptador y el onItemClick ().

Permítanme explicar. En getView (), hay código

 if (mIdList.get(position).id == selectList.get(i).id) 

Nota: Esto comprueba el valor de selectList , que ni siquiera se declara en esta clase Adapter. Supongo que mSelectList decir mSelectList . Pero sigamos adelante …

En onItemClick (), hay código

 if (idList.get(position).id == selectID) { ... selectList.remove(i); ... 

Nota: Este código elimina un elemento de selectList , mientras que en getView (), está comprobando el mismo objeto. No podemos saber qué código se ejecutará primero. Pero tengo una idea … getView () es un método de devolución de llamada virtual donde el BaseAdapter puede activar el método cuando se requiere una fila o elemento para mostrar. Por lo tanto, cuando quita un elemento de un ListView, el adaptador no puede solicitar una actualización, independientemente de lo que haga en código. Y el adaptador ShowItemAdapter es responsable de todas las filas / vistas de actualización.

Sugerencia : Coloque el mismo código (para eliminar / añadir elemento) en getView () para evitar este tipo de conflictos de código.

Háganos saber y buena suerte con esta extraña anomalía.
Tommy Kwee

Necesita llamar a métodos super en las funciones constructor y onFinishInflate de la clase MyListView . Eso podría haber causado el problema.

 public MyListView(Context context) { super(context); selectList = new ArrayList<SELECT_ITEM>(); .. .. } 

y

  @Override protected void onFinishInflate() { super.onFinishInflate(); setOnItemClickListener(this); } 

Es el error en Android 4.0.3, notifyDataSetChanged no funciona desde onItemClickListener .

Así que la solución sería algo como esto:

  1. Establecer onItemClickListener separado para cada vista en el adaptador
  2. Envíelo a donde quiera que quiera manejarlo
  3. Haz lo que quieras y llama a notifyDataSetChanged desde allí

Normalmente, actualizo los datos de mi adaptador, y no tengo este tipo de problema, creo que es más sólido. Puesto que usted está actualizando datos (selectList) en el Listview, la actualización / actualización es un poco indirecta, creo. Yo sugeriría en un primer intento.

Codifique las muestras después del código siguiente:

 selectList.remove(i); showAdapter.notifyDataSetChanged(); 

ADD :

  1. Invalidate () O
  2. InvalidateViews ()

Nota: Me doy cuenta de su solución de llamada onInit () que no tengo ni idea de lo que es. Parece que hay un problema de tiempo involucrado, lo que significa que no debería tener que ejecutar el código en un nuevo hilo / separado.

Abajo podría ayudar. Tuve un problema similar en 4.4.2 y esto ayudó:

 //clear the adapter showAdapter.clear(); //add all the data in your list to adapter again showAdapter.addAll(selectList); 

No es necesario llamar a notifyDataSetChanged ya que lo hará en addAll. Espero que ayude.

Debe actualizar su ListView sincrónicamente.

  public final class ShowItemAdapter extends BaseAdapter{ public ArrayList<ID_ITEM> mIdList; public ArrayList<SELECT_ITEM> mSelectList; public ShowItemAdapter(Context context, ArrayList<ID_ITEM> idList, ArrayList<SELECT_ITEM> selectList) { mIdList = idList; mSelectList = selectList; } public synchronized void refreshData(ArrayList<SELECT_ITEM> items) { this.mSelectList = items; notifyDataSetChanged(); } 

A continuación, llame al método refreshData () siempre que realice cambios en su lista

  selectList.remove(i); refreshData(selectList); 

o

  selectList.add(i); refreshData(selectList); 

Esto definitivamente actualizará la vista de la lista de usuarios con la lista de elementos actualizada

He encontrado una solución, aunque todavía funciona con algunos problemas.
Llamo a continuación en Activity.onCreate (), y sólo en onInit () MyListView será rubricado:

  postDelayed(new Runnable() { public void run() { onInit(icicle); // initial ui } }, 100); 

Hace que la vista se muestre más lenta pero funciona bien.
Si se retrasa alrededor de 100 milisegundos, podría hacer que los teléfonos de trabajo fino se convierten en malos. Retrasado alrededor de 350 mili-segundos hace que ambos teléfonos funcionen bien. ¿Hay mejores respuestas?

En lugar de usar showAdapter.notifyDataSetChanged(); Sólo actualizar su fuente de datos Me refiero a selectList y reinicializar su adaptador y adjuntarlo a la ListView.

Reemplazar esto

 selectList.remove(i); showAdapter.notifyDataSetChanged(); 

y

 selectList.add(item); showAdapter.notifyDataSetChanged(); 

Con esto respectivamente

 selectList.remove(i); // or selectList.add(item); showAdapter = new ShowItemAdapter(context, idList, selectList); setAdapter(showAdapter); 
  • Desplazar una Galería activa el estado presionado y elimina el escucha de clics de los sub-elementos
  • Cómo obtener la miniatura de Android Contact
  • Utilizando una casilla de verificación con un enfoque en blanco falso, impide que los clics de vista de lista
  • ListView se rellena desde la parte inferior en lugar de desde la parte superior
  • Vista de lista de Android con el problema de la casilla de verificación
  • Desplácese ListView sin problemas y programáticamente
  • Fuente y color del listview del cambio del androide
  • Android listviews: vistas de encabezado y pie de página
  • Motorola Droid X, Android 2.3.3 divisor de filas de vista de lista
  • NotifyDataSetChange no funciona desde un adaptador personalizado
  • Custom ListView con cabecera con pin, causando Jank al ajustar el relleno
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.