Risposte:
Supponiamo che tu generi un gruppo di visualizzazioni simili. È possibile impostare un OnClickListener
per ogni vista singolarmente:
button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
...
Quindi devi creare un onClick
metodo univoco per ogni vista anche se fanno cose simili, come:
public void onClick(View v) {
doAction(1); // 1 for button1, 2 for button2, etc.
}
Questo perché onClick
ha solo un parametro, a View
, e deve ottenere altre informazioni dalle variabili di istanza o variabili locali finali negli ambiti racchiusi. Ciò che vogliamo veramente è ottenere informazioni dalle opinioni stesse .
Inserisci getTag
/ setTag
:
button1.setTag(1);
button2.setTag(2);
Ora possiamo usare lo stesso OnClickListener per ogni pulsante:
listener = new OnClickListener() {
@Override
public void onClick(View v) {
doAction(v.getTag());
}
};
Fondamentalmente è un modo per le viste di avere ricordi .
public void ui_click(View view){ if(20==((int)view.getTag())) view.setBackgroundColor(colorInt); }
dovrebbe fare il trucco per la parte a colori. 20 è solo un segnaposto per la posizione di convalida della vista.
Vorrei aggiungere qualche parola.
Anche se l'utilizzo get/setTag(Object)
sembra essere molto utile nel caso particolare di un modello ViewHolder, consiglierei di pensarci due volte prima di usarlo in altri casi. C'è quasi sempre un'altra soluzione con un design migliore.
Il motivo principale è che un codice del genere diventa insostenibile abbastanza rapidamente.
Non è ovvio per altri sviluppatori cosa hai progettato per archiviare come tag nella vista. I metodi setTag/getTag
non sono affatto descrittivi.
Memorizza solo un Object
, che richiede di essere lanciato quando vuoi getTag
. È possibile ottenere arresti anomali imprevisti in seguito quando si decide di modificare il tipo di oggetto memorizzato nel tag.
Ecco una storia di vita reale: abbiamo avuto un progetto piuttosto grande con molti adattatori, operazioni asincrone con viste e così via. Uno sviluppatore ha deciso di set/getTag
inserire nella sua parte di codice, ma un altro aveva già impostato il tag su questa vista. Alla fine, qualcuno non riuscì a trovare il proprio tag ed era molto confuso. Ci è costato diverse ore per trovare il bug.
setTag(int key, Object tag)
sembra molto meglio, perché puoi generare chiavi univoche per ogni tag (usando le risorse ID ), ma c'è una restrizione significativa per Android <4.0. Dai documenti di Lint:
Prima di Android 4.0, l'implementazione di View.setTag (int, Object) memorizzava gli oggetti in una mappa statica, in cui i valori erano fortemente referenziati. Ciò significa che se l'oggetto contiene riferimenti che rimandano al contesto, il contesto (che indica praticamente tutto il resto) perderà. Se si passa una vista, la vista fornisce un riferimento al contesto che l'ha creata. Allo stesso modo, i detentori di una vista in genere contengono una vista e talvolta anche i cursori sono associati alle viste.
Possiamo usare setTag()
e getTag()
impostare e ottenere oggetti personalizzati secondo le nostre esigenze. Il setTag()
metodo accetta un argomento di tipo Object
e getTag()
restituisce un Object
.
Per esempio,
Person p = new Person();
p.setName("Ramkailash");
p.setId(2000001);
button1.setTag(p);
Questo è molto utile per l' ArrayAdapter
utilizzo personalizzato . È una sorta di ottimizzazione. Viene setTag
usato come riferimento all'oggetto che fa riferimento su alcune parti del layout (quella visualizzata in ListView
) anziché 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 differenza degli ID, i tag non vengono utilizzati per identificare le viste. I tag sono essenzialmente un'informazione aggiuntiva che può essere associata a una vista. Vengono spesso utilizzati per comodità per archiviare i dati relativi alle viste nelle viste stesse anziché inserendoli in una struttura separata.
Riferimento: http://developer.android.com/reference/android/view/View.html
L'impostazione dei TAG è davvero utile quando si dispone di un ListView e si desidera riciclare / riutilizzare le visualizzazioni. In questo modo ListView sta diventando molto simile al più recente RecyclerView.
@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;
}