studio programacion para libro edición desarrollo desarrollar aprende aplicaciones android listview null

android - programacion - ListView getChildAt devuelve nulo para niños visibles



programacion android pdf 2017 (8)

Intenté significar siempre en OnListItemClickListener (), pero falla. Por fin hice algunas modificaciones en mi adaptador personalizado para listview. Aquí en getView (), aplico clickListener en el elemento que agregué a la lista con frecuencia. n hacer toda la funcionalidad requerida allí. Aquí está mi código, donde agrego Image View en la lista n, así que aplique listener en imageview.

Creo que ayudará a los que quieran cambiar el color cuando se seleccione un elemento de lista específico>. Ve a por ello..

En getView () del Adaptador personalizado // --------------------------------- código ------- -----------------------------------

LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View rowView = inflater.inflate(R.layout.icon_image_layout, parent, false); ImageView imageView = (ImageView) rowView.findViewById(R.id.Icon_ImageView); imageView.setClickable(true); final int pos=position; imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub // TODO Auto-generated method stub try{ if(previous_view!=null) previous_view.setBackgroundColor(Color.WHITE); }catch (Exception e) { System.out.println("Exception Occurs Previous View"); } v.setBackgroundColor(Color.RED); MainActivity.imageView.setImageResource(MainActivity.Image_Name[pos]); previous_view=v; return false; } });

Obtengo un comportamiento extraño de una lista / el método getChildAt.

Tengo un HashSet, iconsToUpdate, de íconos que han sido cambiados en la base de datos. Quiero iterar sobre las filas visibles para ver si alguno de sus iconos necesita actualizarse para reflejar los nuevos íconos. No es necesario que pruebe los iconos que no están actualmente a la vista, ya que se dibujarán correctamente cuando se procesen.

Mi problema es que getChildAt devuelve nulo cuando parece que no debería. Sé que getChildAt solo puede devolver vistas que están actualmente visibles, pero devuelve nulo para algunas de las filas visibles.

Aquí está mi código que itera sobre las filas visibles:

Logger.debug("First visible index: " + f_listView.getFirstVisiblePosition()); Logger.debug("Last visible index: " + f_listView.getLastVisiblePosition()); for (int i = f_listView.getFirstVisiblePosition(); i <= f_listView.getLastVisiblePosition(); i++) { String tag = "asdf"; // Remove when bug is fixed. if (f_listView == null) { Logger.debug("f_listView is null"); } else if (f_listView.getChildAt(i) == null) { Logger.debug("Child at index " + i + " is null"); } else { tag = (String) f_listView.getChildAt(i).getTag(); Logger.debug("Successful at index " + i + ", tag is: " + tag); } if (iconsToUpdate.contains(tag)) { setIcon(i, f_aim.getInHouseIcon(tag)); } }

Aquí está el registro correspondiente a una ejecución de este ciclo:

D/...: First visible index: 3 D/...: Last visible index: 8 D/...: Successful at index 3, tag is: ... D/...: Successful at index 4, tag is: ... D/...: Successful at index 5, tag is: ... D/...: Child at index 6 is null D/...: Child at index 7 is null D/...: Child at index 8 is null

Cabe señalar que el primer y el último índice visible se informa correctamente, ya que estoy viendo las filas 3-8 cuando ejecuto esto. Las filas 6, 7 y 8 se representan correctamente. ¿Cómo se muestran si son nulos?

Además, no sé si esto es importante, pero la fila 5 es la última fila visible cuando estoy en la parte superior de la lista.

Cualquier información sobre por qué estas filas se devuelven como nulas sería muy apreciada.

¡Gracias!


¿No es porque estás diciendo

f_listView.getChildAt(i)

¿Y deberías recuperar el artículo en esa posición?

f_listView.getItemAtPosition(i)


Cuando llama a listView1.getLastVisiblePosition() y listView1.getFirstVisiblePosition() , la vista de lista devuelve las posiciones de los elementos que son parcialmente visibles en la vista de lista. Por ejemplo, el primer elemento puede ser la mitad visible y el último elemento puede ser la mitad visible. En este caso, aunque puede ver parte del elemento en la vista de lista, el adaptador todavía no ha llamado a la función getView() para el elemento y, por lo tanto, el elemento aún se considera nulo.


En mi caso, tengo un listView y el primer elemento es completamente visible, pero cuando getFirstVisiblePosition() el resultado es 1!

Se vuelve más extraño cuando me desplazo y hago que el primer elemento sea visible a la mitad, entonces mi getView muestra que getFirstVisiblePosition() es 0.

este mi código:

public View getView(final int position, View convertView, final ViewGroup parent) { row = convertView; final AtomPaymentHolder holder = new AtomPaymentHolder(); LayoutInflater inflater = ((Activity) context).getLayoutInflater(); row = inflater.inflate(layoutResourceId, parent, false); row.setTag(items.get(position)); holder.songitem = items.get(position); final int firstPosition = MainActivity.listviewSong.getFirstVisiblePosition() - MainActivity.listviewSong.getHeaderViewsCount(); final int lastPosition = MainActivity.listviewSong.getLastVisiblePosition(); if(MusicService.indexService>= firstPosition && MusicService.indexService<= lastPosition){ MainActivity.listviewSong.getChildAt(MusicService.indexService-firstPosition).setBackgroundColor(getContext().getResources().getColor(R.color.pressed_color)); }

(cuando seleccioné el siguiente elemento y me desplacé, funciona bien)


Sé que esta es una publicación muy antigua. Pero estoy respondiendo porque la gente aún está buscando una getChildAt() excepción del puntero nulo ListView getChildAt() .

Esto se debe a que ArrayApdater está ELIMINANDO y RECICLANDO las vistas que aún no están visibles en el ListView debido a la altura. De modo que si tiene 10 vistas de elementos, y ListView puede mostrar 4 - 5 al mismo tiempo:

El adaptador RETIRA las vistas de elementos en la posición 5 a 9, de modo que cualquier intento de adapter.getChildAt(5... to 9) causará una excepción de puntero nulo

El Adaptador también RECICLA la vista del artículo, de modo que cualquier referencia que haya hecho en la posición 3, por ejemplo, se perderá cuando pase de 5 a 9, y también cualquier Entrada que haga en la posición 3 (Editar Texto, Casilla de verificación, etc.) ser reciclado cuando se desplaza hacia abajo de 5 a 9 y será reutilizado en otra posición más adelante (ex posición 1, 2 o 3, etc.) con el mismo valor

La única forma que encontré para controlar esto es olvidarme de obtener la Vista y tener:

HashMap<Integer, ImageView> iconViews o cualquier tipo que desee para manejar los valores que desea usar para cada elemento de la lista. El primer tipo debe ser único para elementos como item->getId() o position . Inicialícela con new HashMap<>() en el Constructor; en getViews make iconViews.put(position, iconView); Evite que el adaptador use convertView reciclado, elimine la condición if(convertView == null) para que el adaptador siempre infle una nueva instancia de vista. Como la instancia de vista es nueva cada vez, debe establecer el valor de HashMap cada vez, como si ya if(iconViews.containsKey(position)){iconView = iconViews.get(position))}; la clave if(iconViews.containsKey(position)){iconView = iconViews.get(position))}; . Probablemente en este caso no haya toneladas de elementos, por lo que el desplazamiento suave no será obligatorio.

Y finalmente cree métodos públicos para obtener los valores fuera del adaptador que pasa item->getId() Entero como parámetro. public ImageView getIconViewAt(int position) { return iconViews.get(position); } : public ImageView getIconViewAt(int position) { return iconViews.get(position); } public ImageView getIconViewAt(int position) { return iconViews.get(position); } . Será fácil seleccionar Elemento del Adaptador

Ver más de mi answer .


Son parcialmente visibles tal vez. Pero cuando getView () intenta reciclar las vistas se vuelve TOTALMENTE visible, las demás las toman como nulas. por ejemplo, si se desplaza por la lista y el elemento superior es parcialmente visible y la parte inferior es parcialmente visible, por lo que son nulos pero aún se ven.


Tratar

f_listView.getChildAt(positionOfChildYouWantGet - f_listView.getFirstVisiblePosition());


listView.getChildAt (i) funciona donde 0 es la primera fila visible y (n-1) es la última fila visible (donde n es el número de vistas visibles que ve).

El get last / first visible devuelve la posición en el dataAdapter que tiene. Entonces, desde que comienzas en la posición 3, con lo que parecen 6 vistas visibles, es cuando te dan las posiciones 6-8 obtienes nulo.

En su ejemplo, getChildAt (0) devolvería la posición 3. Lo que normalmente hago es almacenar la posición en mis vistas para poder buscar en mi dataAdapter más tarde si necesito valores.

Creo que su bucle for debería verse así:

for (int i = 0; i <= f_listView.getLastVisiblePosition() - f_listView.getFirstVisiblePosition(); i++)

Espero que esto ayude.