¿Cuál es el propósito principal de los métodos setTag() getTag() de View?
¿ Cuál es el objetivo principal de métodos como setTag()
y getTag()
de View
objetos de tipo?
¿Estoy en lo cierto al pensar que puedo asociar cualquier cantidad de objetos con una sola Vista?
Digamos que generas un montón de vistas que son similares. Puede configurar un OnClickListener
para cada vista individualmente:
button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
...
Luego tienes que crear un onClick
método único para cada vista incluso si hacen cosas similares, como:
public void onClick(View v) {
doAction(1); // 1 for button1, 2 for button2, etc.
}
Esto se debe a que onClick
tiene un solo parámetro, a View
, y tiene que obtener otra información de variables de instancia o variables locales finales en ámbitos adjuntos. Lo que realmente queremos es obtener información de las propias vistas .
Ingresar getTag
/ setTag
:
button1.setTag(1);
button2.setTag(2);
Ahora podemos usar el mismo OnClickListener para cada botón:
listener = new OnClickListener() {
@Override
public void onClick(View v) {
doAction(v.getTag());
}
};
Es básicamente una forma de que las vistas tengan recuerdos .
Me gustaría agregar algunas palabras.
Aunque su uso get/setTag(Object)
parece ser muy útil en el caso particular de un patrón ViewHolder, recomendaría pensarlo dos veces antes de usarlo en otros casos. Casi siempre hay otra solución con mejor diseño.
La razón principal es que un código como ese se vuelve insoportable con bastante rapidez.
No es obvio para otros desarrolladores lo que usted diseñó para almacenar como etiqueta en la vista. Los métodos
setTag/getTag
no son en absoluto descriptivos.Simplemente almacena un
Object
, que debe emitirse cuando lo deseegetTag
. Puede sufrir fallos inesperados más adelante cuando decida cambiar el tipo de objeto almacenado en la etiqueta.Aquí hay una historia de la vida real: teníamos un proyecto bastante grande con muchos adaptadores, operaciones asíncronas con vistas, etc. Un desarrollador decidió hacerlo
set/getTag
en su parte del código, pero otro ya había configurado la etiqueta para esta vista. Al final, alguien no pudo encontrar su propia etiqueta y quedó muy confundido. Nos costó varias horas encontrar el error.
setTag(int key, Object tag)
se ve mucho mejor, porque puede generar claves únicas para cada etiqueta (usando recursos de identificación ), pero existe una restricción significativa para Android <4.0. De documentos de Lint:
Antes de Android 4.0, la implementación de View.setTag(int, Object) almacenaba los objetos en un mapa estático, donde los valores estaban fuertemente referenciados. Esto significa que si el objeto contiene referencias que apuntan al contexto, el contexto (que apunta a prácticamente todo lo demás) se filtrará. Si pasa una vista, la vista proporciona una referencia al contexto que la creó. De manera similar, los titulares de vistas suelen contener una vista y, en ocasiones, los cursores también están asociados con las vistas.