Yanıtlar:
Diyelim ki benzer bir grup görünüm oluşturdunuz. OnClickListener
Her görünüm için ayrı ayrı a ayarlayabilirsiniz :
button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
...
Daha sonra onClick
, benzer şeyleri yapsalar bile, her görünüm için benzersiz bir yöntem oluşturmanız gerekir :
public void onClick(View v) {
doAction(1); // 1 for button1, 2 for button2, etc.
}
Bunun nedeni onClick
yalnızca bir parametresi, a View
ve kapsam değişkenlerindeki örnek değişkenlerden veya son yerel değişkenlerden başka bilgi almak zorunda olmasıdır. Gerçekten istediğimiz şey , görüşlerin kendisinden bilgi almaktır .
getTag
/ Girin setTag
:
button1.setTag(1);
button2.setTag(2);
Şimdi her düğme için aynı OnClickListener'ı kullanabiliriz:
listener = new OnClickListener() {
@Override
public void onClick(View v) {
doAction(v.getTag());
}
};
Temel olarak, görünümlerin anılara sahip olmasının bir yolu .
public void ui_click(View view){ if(20==((int)view.getTag())) view.setBackgroundColor(colorInt); }
renk kısmı için hile yapmalı. 20, Görünümünüzün doğrulama konumu için yalnızca bir yer tutucudur.
Birkaç kelime eklemek istiyorum.
Kullanarak rağmen get/setTag(Object)
bir ViewHolder desen özel durumda çok yararlı olabilir gibi görünüyor, ben diğer durumlarda kullanmadan önce iki kez düşünmek öneriyoruz. Neredeyse her zaman daha iyi tasarıma sahip başka bir çözüm var.
Bunun ana nedeni, bu tür kodların oldukça hızlı bir şekilde desteklenmemesidir.
Diğer geliştiriciler için görünümde etiket olarak depolamak için tasarladığınız şey açık değildir. Yöntemler setTag/getTag
hiç tanımlayıcı değildir.
Sadece Object
istediğiniz zaman dökülmesi gereken bir depolar getTag
. Etikette depolanan nesnenin türünü değiştirmeye karar verdiğinizde daha sonra beklenmedik çökmeler alabilirsiniz.
İşte gerçek hayat hikayesi: Çok sayıda adaptör, görünümlü asenkron işlemler vb. İle oldukça büyük bir projemiz vardı. Bir geliştirici set/getTag
kod kısmında karar verdi , ancak başka bir etiket zaten bu görünüme ayarlanmıştı. Sonunda, birisi kendi etiketini bulamadı ve çok karıştı. Hata bulmak için bize birkaç saat mal oldu.
setTag(int key, Object tag)
çok daha iyi görünüyor, çünkü her etiket için benzersiz anahtarlar oluşturabilirsiniz ( id kaynaklarını kullanarak ), ancak Android <4.0 için önemli bir kısıtlama var. Lint belgelerinden:
Android 4.0'dan önce, View.setTag (int, Object) uygulaması, nesnelere değerlerin şiddetle başvurulduğu statik bir haritada depolardı. Bu, nesne içeriğe işaret eden herhangi bir referans içeriyorsa, içeriğin (hemen hemen her şeyi işaret eden) sızıntı yapacağı anlamına gelir. Bir görünüm iletirseniz, görünüm, onu oluşturan bağlama bir başvuru sağlar. Benzer şekilde, görünüm sahipleri tipik olarak bir görünüm içerir ve imleçler bazen görünümlerle de ilişkilendirilir.
Kullanabilir setTag()
ve getTag()
ayarlamak ve almak için özel nesneleri bizim şartının olarak. setTag()
Yöntem türü bir argüman alır Object
, ve getTag()
bir döner Object
.
Örneğin,
Person p = new Person();
p.setName("Ramkailash");
p.setId(2000001);
button1.setTag(p);
Bu, özel kullanım için çok kullanışlıdır ArrayAdapter
. Bir çeşit optimizasyon. Orada setTag
nesneye referans olarak kullanılan düzen bazı parçalarda referansları (görüntüleme bu ListView
yerine) 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);
}
....................
}
Kimliklerin aksine, etiketler görünümleri tanımlamak için kullanılmaz. Etiketler aslında bir görünümle ilişkilendirilebilecek fazladan bir bilgi parçasıdır. Çoğu zaman, görünümlerle ilgili verileri ayrı bir yapıya koymak yerine görünümlerde saklamak için bir kolaylık olarak kullanılırlar.
Referans: http://developer.android.com/reference/android/view/View.html
Bir ListView'a sahip olduğunuzda ve görünümleri geri dönüştürmek / yeniden kullanmak istediğinizde ETİKETLERİN ayarlanması gerçekten yararlıdır. Bu şekilde ListView daha yeni RecyclerView ile çok benzer hale geliyor.
@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;
}