I have a custom dialog which extends Dialog and has a ListView inside its layout. I populate my ListView via a custom adapter which extends ArrayAdapter. Here is my adapter which contains the onClick event for a given list item:
public class PendingTimeslotArrayAdapter extends ArrayAdapter<PendingTimeslot> {
private final Context context;
private final PendingTimeslot[] values;
private final View[] views;
public PendingTimeslotArrayAdapter(Context context, PendingTimeslot[] values) {
super(context, R.layout.mystuff_timeslot_picker_dialog_list_item, values);
this.context = context;
this.values = values;
this.views = new View[values.length];
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(views[position] == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.mystuff_timeslot_picker_dialog_list_item, parent, false);
rowView.setTag((Integer)position);
((TextView)rowView.findViewById(R.id.mystuff_timeslot_picker_list_item_date_time)).setText(values[position].getDateTime());
((TextView)rowView.findViewById(R.id.mystuff_timeslot_picker_list_item_stage_name)).setText(values[position].getStageName());
rowView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("getting touch event");
PendingTimeslot t = values[(Integer)(v.getTag())];
CheckBox checkBox = (CheckBox) v.findViewById(R.id.mystuff_timeslot_picker_list_item_checkbox);
checkBox.setChecked(!checkBox.isChecked());
t.toggle();
}
});
views[position] = rowView;
return rowView;
}
else
return views[position];
}
}
My problem is that when list items are clicked, they do not get touch events, hence my onClick does not get called. Funny thing is, the ListView is fully scrollable and when an item goes out of the visible region and comes back, it becomes touchable and the onClick event is fired.
I tried overriding the ListView and its onTouchEvent method; when an item is clicked, the onTouchEvent on the ListView is really not fired. I also tried overriding the dispatchTouchEvent method and it works correctly, getting all touch events as it is supposed to.
I have used a similar custom ArrayAdapter elsewhere (but not within a Dialog) and it works flawlessly. I am now considering this to be a bug. Am I missing something or should I do this (ListView with clickable items inside a Dialog) another way?
Edit:
Adding
rowView.setClickable(true);
rowView.setFocusable(true);
does absolutely nothing.
Edit2:
Setting an onItemClickListener for my ListView does not work either, even for the items which are scrolled out of and back into the visible region.
Edit3:
I also noticed that when there are 16 items (not a special number) in the ListView, the last 5 items do not get the height I specified (e.g 100px) in the layout I inflate, they behave like wrap_content instead. All in all, I’m starting to believe that a ListView should not be used in a Dialog.
One possible solution I found is to quit trying to use a ListView and instead use a ScrollView with a vertical LinearLayout inside. The layout of this ScrollView is like this:
After I get the list data, I inflate a row for each of them and add them to the LinearLayout manually:
timeslotList is the LinearLayout I mentioned. This workaround works as expected. Still, I’m feeling very stupid having to use ScrollViews instead of ListViews when they are perfect for the job.