Apa tujuan utama metode tampilan setTag () getTag ()?

421

Apa tujuan utama metode seperti setTag()dan getTag()dari Viewjenis benda?

Apakah saya benar dalam berpikir bahwa saya dapat mengaitkan sejumlah objek dengan satu Tampilan?

Eugene
sumber

Jawaban:

636

Katakanlah Anda menghasilkan banyak tampilan yang serupa. Anda dapat mengatur OnClickListeneruntuk setiap tampilan secara individual:

button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
 ...

Maka Anda harus membuat onClickmetode unik untuk setiap tampilan meskipun mereka melakukan hal serupa, seperti:

public void onClick(View v) {
    doAction(1); // 1 for button1, 2 for button2, etc.
}

Ini karena onClickhanya memiliki satu parameter, a View, dan harus mendapatkan informasi lain dari variabel instan atau variabel lokal akhir dalam melampirkan cakupan. Yang kami inginkan adalah mendapatkan informasi dari pandangan sendiri .

Masukkan getTag/ setTag:

button1.setTag(1);
button2.setTag(2);

Sekarang kita bisa menggunakan OnClickListener yang sama untuk setiap tombol:

listener = new OnClickListener() {
    @Override
    public void onClick(View v) {
        doAction(v.getTag());
    }
};

Ini pada dasarnya cara bagi pandangan untuk memiliki ingatan .

Matthew Willis
sumber
8
@Matthew Willis tetapi kita bisa melakukannya menggunakan view.getId () juga. Bukankah begitu ?
Android Killer
50
@AndroidKiller Anda bisa, tetapi dengan setTag () Anda dapat meletakkan objek apa pun yang Anda inginkan, bahkan kelas khusus - sehingga Anda dapat menggunakannya untuk tetap menggunakan referensi ke data yang ditampilkan oleh tampilan
Daniel
Apa yang harus saya lakukan jika saya hanya ingin mengubah warna latar belakang tombol yang diklik ??? Saya mendapatkan posisi dengan getTag ().
Sagar Devanga
2
@Agar: public void ui_click(View view){ if(20==((int)view.getTag())) view.setBackgroundColor(colorInt); }harus melakukan trik untuk bagian warna. 20 hanyalah pengganti untuk posisi validasi Tampilan Anda.
RiA
Saya pikir ini adalah cara lama. cara baru adalah dengan menggunakan argumen umum yang memberikan keamanan tipe. tapi ini tetap baik.
M.kazem Akhgary
124

Saya ingin menambahkan beberapa kata.

Meskipun menggunakan get/setTag(Object)tampaknya sangat berguna dalam kasus tertentu dari pola ViewHolder, saya akan merekomendasikan untuk berpikir dua kali sebelum menggunakannya dalam kasus lain. Hampir selalu ada solusi lain dengan desain yang lebih baik.

Alasan utamanya adalah kode seperti itu menjadi tidak dapat didukung dengan cepat.

  • Tidak jelas bagi pengembang lain apa yang Anda rancang untuk disimpan sebagai tag di tampilan. Metodenya setTag/getTagtidak deskriptif sama sekali.

  • Ini hanya menyimpan Object, yang perlu dilemparkan ketika Anda mau getTag. Anda bisa mendapatkan crash yang tidak terduga nanti ketika Anda memutuskan untuk mengubah jenis objek yang disimpan dalam tag.

  • Inilah kisah nyata: Kami memiliki proyek yang cukup besar dengan banyak adaptor, operasi async dengan pandangan dan sebagainya. Satu pengembang memutuskan untuk set/getTagmenjadi bagian dari kodenya, tetapi yang lain telah menetapkan tag pada tampilan ini. Pada akhirnya, seseorang tidak dapat menemukan tag sendiri dan sangat bingung. Kami butuh beberapa jam untuk menemukan bug.

setTag(int key, Object tag)terlihat jauh lebih baik, karena Anda dapat membuat kunci unik untuk setiap tag (menggunakan sumber daya id ), tetapi ada batasan yang signifikan untuk Android <4.0. Dari Lint docs:

Sebelum Android 4.0, implementasi View.setTag (int, Object) akan menyimpan objek dalam peta statis, di mana nilainya sangat direferensikan. Ini berarti bahwa jika objek berisi referensi yang menunjuk kembali ke konteks, konteks (yang menunjuk ke hampir semua yang lain) akan bocor. Jika Anda melewati tampilan, tampilan menyediakan referensi ke konteks yang membuatnya. Demikian pula, pemegang tampilan biasanya berisi tampilan, dan kursor terkadang juga dikaitkan dengan tampilan.

Andrei Buneyeu
sumber
2
Terima kasih, sangat membantu! ... Apakah Anda mengetahui jika tag apa yang ada dipulihkan di antara rekreasi aktivitas?
gunar
25

Kita dapat menggunakan setTag()dan getTag()untuk mengatur dan mendapatkan objek kustom sesuai kebutuhan kita. The setTag()Metode membawa argumen dari jenis Object, dan getTag()mengembalikan sebuah Object.

Sebagai contoh,

Person p = new Person();
p.setName("Ramkailash");
p.setId(2000001);
button1.setTag(p);
Ramkailash
sumber
20

Untuk pengembang web, ini tampaknya setara dengan data- ..

Oren
sumber
14

Ini sangat berguna untuk ArrayAdapterpenggunaan khusus . Ini semacam optimisasi. Ada yang setTagdigunakan sebagai referensi untuk objek yang referensi pada beberapa bagian tata letak (yang menampilkan ListView) bukan 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);
    }
            ....................
}
shubniggurath
sumber
13

Tidak seperti ID, tag tidak digunakan untuk mengidentifikasi tampilan. Tag pada dasarnya adalah sepotong informasi tambahan yang dapat dikaitkan dengan tampilan. Mereka paling sering digunakan sebagai kenyamanan untuk menyimpan data yang terkait dengan tampilan dalam tampilan itu sendiri daripada dengan menempatkannya dalam struktur yang terpisah.

Referensi: http://developer.android.com/reference/android/view/View.html

Saad Bilal
sumber
11

Pengaturan TAG sangat berguna ketika Anda memiliki ListView dan ingin mendaur ulang / menggunakan kembali tampilan. Dengan cara itu ListView menjadi sangat mirip dengan RecyclerView yang lebih baru.

@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;
}

sumber