回答:
類似したビューの束を生成するとします。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());
}
};
これは基本的に、ビューに思い出を持たせる方法です。
public void ui_click(View view){ if(20==((int)view.getTag())) view.setBackgroundColor(colorInt); }
カラー部分のトリックを行う必要があります。20は、ビューの検証位置の単なるプレースホルダーです。
少し言葉を付け加えたいのですが。
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)の実装は、オブジェクトが静的マップに格納され、値が強く参照されていました。これは、オブジェクトにコンテキストを指す参照が含まれている場合、コンテキスト(他のほとんどすべてを指す)がリークすることを意味します。ビューを渡すと、ビューはそれを作成したコンテキストへの参照を提供します。同様に、ビューホルダーには通常ビューが含まれ、カーソルもビューに関連付けられることがあります。
これはカスタム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);
}
....................
}
IDとは異なり、タグはビューの識別には使用されません。タグは基本的に、ビューに関連付けることができる追加の情報です。これらは、ビューに関連するデータを別の構造に置くのではなく、ビュー自体に格納するための便宜として最もよく使用されます。
リファレンス:http : //developer.android.com/reference/android/view/View.html
タグの設定は、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;
}