タイトルにあるように、アイテム内のビューをクリックしたときのアイテムの正確な位置を知りたいです。
ArrayAdapterのgetView()メソッド内に次のコードがあるとします。
...
holder = new ViewHolder ();
holder.iconAction = (ImageView)convertView.findViewById (R.id.download_item_iconAction);
holder.iconAction.setOnClickListener (new View.OnClickListener(){
@Override
public void onClick (View v){
//Item X is clicked
}
});
...
onClick()内で、クリックされたビューvはわかりますが、アイテムの位置はわかりません。
トリックをしましょう。getView()がビューを作成するときに、ViewHolderに位置を保存します。
public View getView (int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null){
holder = new ViewHolder ();
holder.iconAction = (ImageView)convertView.findViewById (id);
holder.iconAction.setOnClickListener (new View.OnClickListener(){
@Override
public void onClick (View v){
int pos = (Integer)v.getTag ();
}
});
holder.iconWait.setTag (position);
...
}else{
holder = (ViewHolder)convertView.getTag ();
}
...
}
このコードは機能します...しかし常にではありません。リストをスクロールしてすべてのアイテムを表示する必要がある場合は、ビューがリサイクルされます。リストに10個の要素があり、5個だけが表示されているとします(表示とは、アイテムの1ピクセルの線が表示されている場合、このアイテムが表示されていることを意味します)。ここで、下にスクロールすると6番目の要素が表示されますが、最初の(0)は引き続き表示されます。もう少しスクロールすると、最初の要素が非表示になり、7番目の要素が表示されますが、この新しい要素のビューは最初の要素(0)のビューです。
位置を保存しています:0、1、2、3、4、5。7番目の要素(6)は位置0を保存します:間違っています。
クリックコールバックを取得する別の方法は、ListViewのOnItemClickListenerリスナーを使用することです。
listView = getListView ();
listView.setOnItemClickListener (new AdapterView.OnItemClickListener(){
@Override
public void onItemClick (AdapterView<?> parentView, View childView, int position, long id){
...
}
});
下にスクロールすると正確な位置がわかりますが、この方法では、クリックされた子ビューに関係なく、アイテムがクリックされたときにコールバックを受け取ります。
ありがとう。