android - programacion - Redibuja una sola fila en una vista de lista
manual de programacion android pdf (4)
Esta pregunta ya tiene una respuesta aquí:
- Android ListView Refresh Single Row 6 respuestas
¿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();
}
});
}