A veces listView.getChildAt (int index) devuelve NULL (Android)

Tengo un listView con un adaptador de encargo. Cuando algo sucede (un clic en un niño) Hago algunas cosas de cálculo y modificar el niño Ver. SI se ha cumplido alguna condición, se debe modificar otro niño no relacionado con el niño que ha hecho clic.

Esto a veces funciona, pero a veces falla y el DDMS dice que la vista es nula …

Déjame mostrarte el código:

if(invalidaEste != -1) { try { View v = lv_data.getChildAt(invalidaEste); if( v== null) { Log.e("MY_LOG", "SIZE " + lv_data.getCount()); Log.e("MY_LOG", "IS_NULL " + String.valueOf(invalidaEste)); } if(invalidaEste >= lv_data.getFirstVisiblePosition() && invalidaEste <= lv_data.getLastVisiblePosition()) { RelacionFacturaPago rpf = (RelacionFacturaPago)lv_data.getAdapter().getItem(invalidaEste); TextView tv = (TextView)v.findViewById(R.id.tv_pendiente); tv.setText(Formato.double2Screen(rpf.getPorPagar())); } } catch (Exception e) { Log.e("MY_LOG", "FAIL"); Log.e("MY_LOG", String.valueOf(invalidaEste)); } } 

InvalidaEste es la vista que quiero modificar. Cuando v es nulo , registro el índice para comprobar si está bien. Siempre es menor o igual que el listView.getCount ()

¿Por qué está pasando esto?

Más datos: El código está dentro de la onAnimationStart (animación de animación) de un listener AnimationListener.

Debido al reciclado de vista, listView.getChildAt() sólo devolverá una vista para las posiciones que está mostrando, y tal vez una más. Tal vez si comparte más de su código podemos ayudarle a averiguar cómo abordar mejor el problema.

Dmon y Azertiti son correctos … una vez que su lista se desplaza usted se encuentra en problemas. Si la vista no es visible, entonces no existe (es decir, ha sido reciclada por Android). Volverá a crear la vista una vez que se despliegue.

Hacer algo como esto debería funcionar:

 View view; int nFirstPos = lv_data.getFirstVisiblePosition(); int nWantedPos = invalidaEste - nFirstPos; if ((nWantedPos >= 0) && (nWantedPos <= lv_data.getChildCount()) { view = lv_data.getChildAt(nWantedPos); if (view == null) return; // else we have the view we want } 

Si ese niño no es visible en la pantalla, significa que no hay vista para ello. Creo que este no es tu caso de trabajo.

Una buena práctica es cambiar los datos detrás de su adaptador de lista y llamar a notifyDataSetChanged () en el adaptador. Esto informará a la lista que el adaptador ha cambiado y vuelva a pintar las vistas.

Si realmente desea actualizar manualmente la vista, supongo que la única solución es retener los nuevos valores en algún lugar y esperar hasta que la vista se vuelva visible. En ese momento usted tiene una referencia válida y puede hacer las actualizaciones.

Lo pruebo con una línea de código cuando necesito ir dentro de una posición válida de un Listview. Aquí están sus variables usadas como un ejemplo. Donde lv_data es el ListView y tv es tu TextView.

 if ( lv_data.getChildAt(lv_data.getPositionForView(tv)) != null) { int position = lv_data.getPositionForView(tv); } 
  • La llamada a `getDrawingCache` devuelve null cuando se habilita el desplazamiento
  • Vista vacía en el adaptador de lista expandible
  • agregar vista (vista de texto) en AsyncTask
  • Custom Seekbar con efecto de enmascarar con dos estirables?
  • Diseño de vistas personalizadas
  • View.setEnabled (false) no funciona muy bien en android
  • ¿Hay problemas en la vista Web de Android para SVG? Nivel API 16 +
  • Cómo iniciar dos animaciones en dos vistas diferentes en API lvl 19
  • ¿Cómo puedo ver que View se vuelve visible
  • ¿Cómo puedo obtener el tamaño del lienzo de una vista personalizada fuera del método onDraw?
  • OnTouch funciona, pero OnClickListener no?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.