SetTag () getTag () yöntemlerinin ana amacı nedir?


421

Gibi yöntemlerin temel amacı nedir setTag()ve getTag()bir Viewtür nesneler?

Herhangi bir sayıda nesneyi tek bir Görünüm ile ilişkilendirebileceğimi düşünmekte haklı mıyım?

Yanıtlar:


636

Diyelim ki benzer bir grup görünüm oluşturdunuz. OnClickListenerHer 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 onClickyalnızca bir parametresi, a Viewve 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 .


8
@Matthew Willis ama bunu view.getId () kullanarak da yapabiliriz. değil mi ?
Android Killer

50
@AndroidKiller yapabilirsiniz, ancak setTag () ile özel sınıfları bile istediğiniz herhangi bir nesneyi koyabilirsiniz - böylece bunları, görünümün görüntülediği verilere referansta bulunmak için kullanabilirsiniz
Daniel

Yalnızca tıklatılan düğmenin arka plan rengini değiştirmek istiyorsam ne yapmalıyım ??? Konumu getTag () ile alıyorum.
Sagar Devanga

2
@Sagar: 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.
RiA

Bence bu eski yöntem. yeni yol tip güvenliği sağlayan genel argümanları kullanmaktır. ama yine de bu iyi.
M.kazem Akhgary

124

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/getTaghiç tanımlayıcı değildir.

  • Sadece Objectistediğ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/getTagkod 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.


2
Teşekkürler, çok yardımcı! ... Etiketteki içeriğin etkinlik rekreasyonları arasında geri yüklenip yüklenmediğini biliyor musunuz?
gunar

25

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);

20

Web geliştiricileri için, bu veri ile eşdeğer gibi görünüyor.


14

Bu, özel kullanım için çok kullanışlıdır ArrayAdapter. Bir çeşit optimizasyon. Orada setTagnesneye referans olarak kullanılan düzen bazı parçalarda referansları (görüntüleme bu ListViewyerine) 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);
    }
            ....................
}

13

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


11

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.