ListViewでコード上からOnItemClickをトリガーするperformItemClickだが、何故か長押しバージョンのperformItemLongClickが存在しない問題について。
ListViewにはアイテムがクリックされたときに呼び出されるOnItemClickが存在するが、TwitterクライアントとかだとListViewのアイテムの中にViewを詰め込んだりするので、アイテムではなく中身の個々のViewでOnItemClickをトリガーしたいと思うことは多々ある(よね?)。
まあそういう人なら既にBaseAdapterを継承した自前のAdapterでgetViewに
@Override
public View getView(final int i, View v,final ViewGroup parent) {
if(v==null)
v = layoutInflater.inflate(R.layout.listview,null);
String str=strList.get(i);
Bitmap bitmap=bitmapList.get(i);
TextView username=v.findViewById(R.id.username);
ImageView icon=v.findViewById(R.id.icon);
username.setText(str);
icon.setImageBitmap(bitmap);
final View v_f=v;
username.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
long id=getItemId(i);
((ListView)parent).performItemClick(v_f,i,id); //onItemClickをトリガー
}
});
return v;
}
@Override
public boolean isEnabled(int position){
return false;
}
こんな感じの記述をしているであろうが、
「さて次は長押しされたときにonItemLongClickをトリガーするかーー」
と思ったらperformItemLongClickがないのである。
ないのだ。
ところが実は抜け道がある(人によっては使えないかもしれないが...)。
抜け道とは何かというと、"長押しされてもOnItemClickをトリガーしてしまえばいい"のである。それじゃ単押しのときと処理が被ると思うかもしれないが、心配はいらない。
onItemClickの引数は
AdapterView<?> parent, View view, int i, long id
の4つ。うち最後から2番目は現在のposition。最後の一つは自前のAdapterの中のgetItemId(int position)の戻り値だが、たぶんこうなっているのではないだろうか...
@Override
public long getItemId(int position) {
return position;
}
要するに、id=i
ということである。つまりidは要らない子...ならばこれを使わない手はない。
※裏を返せばonItemClick内でidを使う処理があってかつ id ≠ i のときはこの手は使えないということなので気を付けられたし。
もう薄々気づいているだろうが、onItemClickの中でidの値によって処理を変えるようにすればいいということだ。
onItemClickのほうではidによって処理を分け、
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int i, long id) {
ListView list = (ListView) parent;
switch ((int) id) {
case 0:
//処理 1
break;
case 1:
//処理 2
break;
...
}
}
});
AdapterのgetViewのほうでは単押し/長押しで渡すidを変えればOK
username.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
((ListView)parent).performItemClick(v_f,i,0);//単押しで処理 1を実行
}
});
username.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
((ListView)parent).performItemClick(v_f,i,1);//長押しで処理 2を実行
return true;
}
});
もちろん前述したように処理にidを使う場合にはこの手は効かないので気を付けよう。