Respostas:
Digamos que você gere várias visualizações semelhantes. Você pode definir um OnClickListener
para cada visualização individualmente:
button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
...
Então você deve criar um onClick
método exclusivo para cada visualização, mesmo que eles façam o mesmo, como:
public void onClick(View v) {
doAction(1); // 1 for button1, 2 for button2, etc.
}
Isso ocorre porque onClick
possui apenas um parâmetro, a View
, e precisa obter outras informações de variáveis de instância ou variáveis locais finais nos escopos anexos. O que realmente queremos é obter informações dos próprios pontos de vista .
Digite getTag
/ setTag
:
button1.setTag(1);
button2.setTag(2);
Agora podemos usar o mesmo OnClickListener para cada botão:
listener = new OnClickListener() {
@Override
public void onClick(View v) {
doAction(v.getTag());
}
};
É basicamente uma maneira de as visualizações terem memórias .
public void ui_click(View view){ if(20==((int)view.getTag())) view.setBackgroundColor(colorInt); }
deve fazer o truque para a parte da cor. 20 é apenas um espaço reservado para a posição de validação da sua visualização.
Eu gostaria de adicionar algumas palavras.
Embora o uso get/setTag(Object)
pareça ser muito útil no caso específico de um padrão ViewHolder, recomendo pensar duas vezes antes de usá-lo em outros casos. Quase sempre há outra solução com melhor design.
A principal razão é que um código como esse se torna insuportável rapidamente.
Não é óbvio para outros desenvolvedores o que você projetou para armazenar como tag na exibição. Os métodos setTag/getTag
não são descritivos.
Ele apenas armazena um Object
, que precisa ser convertido quando você desejar getTag
. Você pode obter falhas inesperadas mais tarde quando decide alterar o tipo de objeto armazenado na tag.
Aqui está uma história da vida real: tivemos um projeto bastante grande com muitos adaptadores, operações assíncronas com visualizações e assim por diante. Um desenvolvedor decidiu set/getTag
em sua parte do código, mas outro já havia definido a tag para essa visualização. No final, alguém não conseguiu encontrar sua própria etiqueta e ficou muito confuso. Nos custou várias horas para encontrar o bug.
setTag(int key, Object tag)
parece muito melhor, pois você pode gerar chaves exclusivas para cada tag (usando recursos de identificação ), mas há uma restrição significativa para o Android <4.0. Dos documentos do Lint:
Antes do Android 4.0, a implementação do View.setTag (int, Object) armazenava os objetos em um mapa estático, onde os valores eram fortemente referenciados. Isso significa que, se o objeto contiver referências que apontem para o contexto, o contexto (que aponta para praticamente todo o resto) vazará. Se você passar por uma visão, a visão fornecerá uma referência ao contexto que a criou. Da mesma forma, os detentores de exibição geralmente contêm uma exibição, e os cursores também são associados às visualizações.
Podemos usar setTag()
e getTag()
definir e obter objetos personalizados conforme nossa exigência. O setTag()
método pega um argumento do tipo Object
e getTag()
retorna um Object
.
Por exemplo,
Person p = new Person();
p.setName("Ramkailash");
p.setId(2000001);
button1.setTag(p);
Isso é muito útil para ArrayAdapter
uso personalizado . É algum tipo de otimização. É setTag
usado como referência ao objeto que faz referência em algumas partes do layout (que são exibidas ListView
) em vez 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);
}
....................
}
Ao contrário dos IDs, as tags não são usadas para identificar visualizações. As tags são essencialmente uma informação extra que pode ser associada a uma exibição. Eles costumam ser usados como uma conveniência para armazenar dados relacionados às visualizações nas próprias visualizações, em vez de colocá-los em uma estrutura separada.
Referência: http://developer.android.com/reference/android/view/View.html
A configuração de TAGs é realmente útil quando você possui um ListView e deseja reciclar / reutilizar as visualizações. Dessa forma, o ListView está se tornando muito semelhante ao RecyclerView mais recente.
@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;
}