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.
- ¿Por qué el perro String.format de android es lento?
- Problema de menú emergente en Android ListView
- MVVMCross cambiando ViewModel dentro de un MvxBindableListView
- Agregar la barra de progreso en la parte inferior de una vista de lista
- Android: nesting FrameLayouts - ¿cuál es la sobrecarga de rendimiento exacto?
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.
- Cómo actualizar la lista expandible cuando se agrega un elemento nuevo
- Android looping infinito ListView?
- ¿Es esto un listview, y cómo hacer esto
- Android StaggeredGridView dentro de la altura de ListView
- Cómo desencadenar onListItemClick en un ListFragment
- No puede hacer clic en la fila listview con imagebutton
- Seleccione sólo un botón de radio de la vista de lista
- ListView personalizado cuando se desplaza cambia aleatoriamente el texto del botón o edittext
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:
- Establecer
onItemClickListener
separado para cada vista en el adaptador - Envíelo a donde quiera que quiera manejarlo
- 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 :
- Invalidate () O
- 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);
- ¿Cuál es la forma correcta de implementar AsyncTask? Estática o no estática clase anidada?
- Keytool's -storepass vs. -keypass – ¿Por qué 2 contraseñas?