studio programacion móviles libros libro desarrollo desarrollar curso aprende aplicaciones android listview view android-arrayadapter redraw

android - programacion - Redibuja una sola fila en una vista de lista



manual de programacion android pdf (4)

Esta pregunta ya tiene una respuesta aquí:

¿Es posible volver a dibujar una sola fila en un ListView ? Tengo un ListView con filas que son LinearLayout . Escucho un cambio de preferencia y, a veces, necesito cambiar solo una View dentro de LinearLayout de una sola fila. ¿Hay alguna forma de volver a dibujar esa fila sin llamar a listview.notifyDatasetChanged() ?

Intenté llamar a view.invalidate () en la vista (dentro de LinearLayout ) pero no vuelve a dibujar la fila.


Como Romain Guy explicó hace un tiempo durante la sesión de Google I / O , la forma más eficiente de actualizar solo una vista en una vista de lista es algo como lo siguiente (esta actualización completa de los datos de View ):

ListView list = getListView(); int start = list.getFirstVisiblePosition(); for(int i=start, j=list.getLastVisiblePosition();i<=j;i++) if(target==list.getItemAtPosition(i)){ View view = list.getChildAt(i-start); list.getAdapter().getView(i, view, list); break; }

Suponiendo que el target es un elemento del adaptador.

Este código recupera el ListView , luego examina las vistas mostradas actualmente, compara el elemento de target que estás buscando con cada elemento de vista que se muestra, y si tu objetivo está entre esos, obtén la vista getView() y ejecuta el adaptador getView() en esa vista para actualizar la pantalla.

Como nota al margen invalidate() no funciona como algunas personas esperan y no actualizará la vista como getView() hace, notifyDataSetChanged() reconstruirá toda la lista y terminará llamando a getview() para cada elemento mostrado e invalidateViews() también afectará a un montón.

Una última cosa, uno también puede obtener un rendimiento adicional si solo necesita cambiar un elemento secundario de una vista de fila y no toda la fila como getView hace getView . En ese caso, el siguiente código puede reemplazar list.getAdapter().getView(i, view, list); (ejemplo para cambiar un texto de TextView ):

((TextView)view.findViewById(R.id.myid)).setText("some new text");

En el código confiamos.


Ponga una etiqueta en la fila que desea actualizar. Cuando desee volver a dibujar esa vista o fila específica, haga

ListView lv = (ListView)findViewById(....)

y entonces

View v = lv.findViewWithTag(tagobject);

y luego haces lo que quieras con la vista.


Romain Guy respondió a esta pregunta en el video "Google IO 2010 El mundo de ListView" en el momento exacto en que se hizo esta pregunta: http://www.youtube.com/watch?feature=player_detailpage&v=wDBM6wVEO70#t=3149s

Entonces, según Romain Guy, eso debería funcionar, y creo que podemos confiar en él.

La razón por la cual su punto de vista no se vuelve a dibujar es un poco misteriosa. Tal vez intente deshabilitar todas las opciones de caché disponibles en listView

setAnimationCacheEnabled(false); setScrollingCacheEnabled(false); setChildrenDrawingCacheEnabled(false); setChildrenDrawnWithCacheEnabled(false);


view.invalidate() no funcionó para mí. Pero esto funciona como un encanto:

Supongamos que está actualizando la posición " position " en la fila. if evitan elementos extraños para volver a dibujar, como texto que se baila cuando se está actualizando una fila que no está en la pantalla.

if (position >= listView.getFirstVisiblePosition() && position <= listView.getLastVisiblePosition()) { runOnUiThread(new Runnable() { @Override public void run() { listView.invalidateViews(); } }); }