Respuestas:
Digamos que genera un montón de vistas que son similares. Puede establecer un OnClickListener
para cada vista individualmente:
button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
...
Luego, debe 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
solo tiene un parámetro, a View
, y tiene que obtener otra información de las variables de instancia o de las variables locales finales en los ámbitos adjuntos. Lo que realmente queremos es obtener información de las propias vistas .
Entrar 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());
}
};
Básicamente es una forma de que las vistas tengan recuerdos .
public void ui_click(View view){ if(20==((int)view.getTag())) view.setBackgroundColor(colorInt); }
debería hacer el truco para la parte de color. 20 es solo un marcador de posición para la posición de validación de su Vista.
Me gustaría agregar algunas palabras.
Aunque el 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 un mejor diseño.
La razón principal es que un código como ese deja de ser compatible con bastante rapidez.
No es obvio para otros desarrolladores lo que diseñó para almacenar como etiqueta en la vista. Los métodos setTag/getTag
no son descriptivos en absoluto.
Simplemente almacena un Object
, que requiere ser lanzado cuando quieras getTag
. Puede obtener bloqueos inesperados más adelante cuando decida cambiar el tipo de objeto almacenado en la etiqueta.
Aquí hay una historia de la vida real: tuvimos un proyecto bastante grande con muchos adaptadores, operaciones asincrónicas con vistas, etc. Un desarrollador decidió set/getTag
en su parte del código, pero otro ya había establecido la etiqueta para esta vista. Al final, alguien no pudo encontrar su propia etiqueta y estaba 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 hay una restricción significativa para Android <4.0. De documentos de pelusa:
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 casi todo lo demás) se filtrará. Si pasa una vista, la vista proporciona una referencia al contexto que la creó. Del mismo modo, los titulares de vistas suelen contener una vista, y los cursores a veces también están asociados con vistas.
Podemos usar setTag()
y getTag()
establecer y obtener objetos personalizados según nuestros requisitos. El setTag()
método toma un argumento de tipo Object
y getTag()
devuelve un Object
.
Por ejemplo,
Person p = new Person();
p.setName("Ramkailash");
p.setId(2000001);
button1.setTag(p);
Esto es muy útil para ArrayAdapter
uso personalizado . Es algún tipo de optimización. Se setTag
usa como referencia al objeto que hace referencia en algunas partes del diseño (que se muestra en ListView
) en lugar de findViewById
.
static class ViewHolder {
TextView tvPost;
TextView tvDate;
ImageView thumb;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = myContext.getLayoutInflater();
convertView = inflater.inflate(R.layout.postitem, null);
ViewHolder vh = new ViewHolder();
vh.tvPost = (TextView)convertView.findViewById(R.id.postTitleLabel);
vh.tvDate = (TextView)convertView.findViewById(R.id.postDateLabel);
vh.thumb = (ImageView)convertView.findViewById(R.id.postThumb);
convertView.setTag(vh);
}
....................
}
A diferencia de los ID, las etiquetas no se utilizan para identificar vistas. Las etiquetas son esencialmente una información adicional que se puede asociar con una vista. Se utilizan con mayor frecuencia como una conveniencia para almacenar datos relacionados con vistas en las vistas en sí, en lugar de colocarlos en una estructura separada.
Referencia: http://developer.android.com/reference/android/view/View.html
La configuración de TAG es realmente útil cuando tiene un ListView y desea reciclar / reutilizar las vistas. De esa manera, ListView se está volviendo muy similar al RecyclerView más nuevo.
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = null;
if ( convertView == null )
{
/* There is no view at this position, we create a new one.
In this case by inflating an xml layout */
convertView = mInflater.inflate(R.layout.listview_item, null);
holder = new ViewHolder();
holder.toggleOk = (ToggleButton) convertView.findViewById( R.id.togOk );
convertView.setTag (holder);
}
else
{
/* We recycle a View that already exists */
holder = (ViewHolder) convertView.getTag ();
}
// Once we have a reference to the View we are returning, we set its values.
// Here is where you should set the ToggleButton value for this item!!!
holder.toggleOk.setChecked( mToggles.get( position ) );
return convertView;
}