ビューのsetTag()getTag()メソッドの主な目的は何ですか?


421

などの方法の主な目的は何であるsetTag()getTag()Viewタイプのオブジェクト?

任意の数のオブジェクトを単一のビューに関連付けることができると私は思っていますか?

回答:


636

類似したビューの束を生成するとします。OnClickListenerビューごとに個別に設定できます。

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

次にonClick、ビューが同じようなことをする場合でも、ビューごとに一意のメソッドを作成する必要があります。

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

これは、onClickパラメータが1つしかないためでありView、インスタンス変数または他のスコープ内の最終的なローカル変数から他の情報を取得する必要があります。私たちが本当に望んでいるのは、ビュー自体から情報を取得することです。

getTag/を入力setTag

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

これで、すべてのボタンに同じOnClickListenerを使用できます。

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

これは基本的に、ビューに思い出を持たせる方法です。


8
@Matthew Willisですが、view.getId()を使用してそれを行うこともできます。そうではありませんか ?
Android Killer

50
@AndroidKillerは可能ですが、setTag()を使用すると、カスタムクラスを含め、任意のオブジェクトを配置できます。そのため、それらを使用して、ビューが表示しているデータへの参照を永続化できます
Daniel

クリックされたボタンの背景色のみを変更したい場合はどうすればよいですか?getTag()で位置を取得しています。
Sagar Devanga 2015年

2
@Sagar:public void ui_click(View view){ if(20==((int)view.getTag())) view.setBackgroundColor(colorInt); }カラー部分のトリックを行う必要があります。20は、ビューの検証位置の単なるプレースホルダーです。
RiA 2016年

これは古い方法だと思います。新しい方法は、タイプセーフを提供する汎用引数を使用することです。それでもそれは良いことです。
M.kazem Akhgary

124

少し言葉を付け加えたいのですが。

get/setTag(Object)ViewHolderパターンの特定のケースでは使用が非常に役立つようですが、他のケースでは使用する前によく考えることをお勧めします。ほとんどの場合、より良い設計の別のソリューションがあります。

主な理由は、このようなコードがすぐにサポートできなくなることです。

  • ビューにタグとして保存するように設計したものは、他の開発者にとって自明ではありません。メソッドsetTag/getTagはまったく説明的ではありません。

  • 格納するだけでObject、必要なときにキャストする必要がありますgetTag。後でタグに格納されているオブジェクトのタイプを変更すると、予期しないクラッシュが発生する可能性があります。

  • これが実際の話です。多くのアダプター、ビューを使用した非同期操作などを含むかなり大きなプロジェクトがありました。開発者の1人set/getTagはコードの一部を決定しましたが、別の開発者はすでにこのビューにタグを設定しています。結局、誰かが自分のタグを見つけることができず、非常に混乱しました。バグを見つけるのに数時間かかりました。

setTag(int key, Object tag)見栄えが良く、すべてのタグに一意のキーを生成できるため(id resourcesを使用)、Android <4.0には大きな制限があります。Lint docsから:

Android 4.0より前のバージョンでは、View.setTag(int、Object)の実装は、オブジェクトが静的マップに格納され、値が強く参照されていました。これは、オブジェクトにコンテキストを指す参照が含まれている場合、コンテキスト(他のほとんどすべてを指す)がリークすることを意味します。ビューを渡すと、ビューはそれを作成したコンテキストへの参照を提供します。同様に、ビューホルダーには通常ビューが含まれ、カーソルもビューに関連付けられることがあります。


2
ありがとう、とても役に立ちました!...アクティビティのレクリエーションの間にタグの内容が復元されるかどうかを偶然知っていますか?
ガンナー2013年

25

を使用setTag()getTag()て、要件に応じてカスタムオブジェクトを設定および取得できます。setTag()この方法は、型の引数を取りObject、そしてgetTag()返しますObject

例えば、

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


14

これはカスタムArrayAdapter使用に非常に役立ちます。それはある種の最適化です。そこsetTag(に表示することがレイアウトの一部に参照するオブジェクトへの参照として使用されるListView)の代わり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

IDとは異なり、タグはビューの識別には使用されません。タグは基本的に、ビューに関連付けることができる追加の情報です。これらは、ビューに関連するデータを別の構造に置くのではなく、ビュー自体に格納するための便宜として最もよく使用されます。

リファレンス:http : //developer.android.com/reference/android/view/View.html


11

タグの設定は、ListViewがあり、ビューをリサイクル/再利用する場合に非常に役立ちます。このようにして、ListViewは新しい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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.