I use a custom array adapter for a spinner. However, when selecting an item in the dropdown list, the dropdown list stays there, and the spinner doesn't get updated, which is misbehaviour (compared to using a generic array adapter with string). This is the custom class. Am I missing anything? thanks.
public class CalendarNameAdapter extends ArrayAdapter<AgendaLogic.ExternalCalendarInfo> {
Context mContext ;
ArrayList<AgendaLogic.ExternalCalendarInfo> mCalendarLayers;
public CalendarNameAdapter(Context context, int resource, ArrayList<AgendaLogic.ExternalCalendarInfo> objects) {
super(context, resource, objects);
mContext = context;
mCalendarLayers = objects;
}
@Override
public void add(AgendaLogic.ExternalCalendarInfo object) {
mCalendarLayers.add(object);
}
@Override
public int getCount() {
return mCalendarLayers.size();
}
private class ViewHolder{
Button button;
TextView textView;
public ViewHolder(Button _btn, TextView _tv){
button = _btn;
textView = _tv;
}
}
public View getView(int position, View convertView, final ViewGroup parent) {
View view =convertView;
if (view==null){
view = View.inflate(mContext,R.layout.li_calendar_display, null);
Button button = (Button) view.findViewById(R.id.calColor);
TextView name = (TextView) view.findViewById(R.id.calName);
view.setTag(new ViewHolder(button, name));
}
ViewHolder viewHolder = (ViewHolder) view.getTag();
viewHolder.button.setBackgroundColor(mCalendarLayers.get(position).color);
viewHolder.textView.setText(mCalendarLayers.get(position).name);
return view;
}
@Override
public View getDropDownView(final int position, View convertView, final ViewGroup parent) {
final View view = getView(position, convertView, parent);
return view;
}
}
This is the usage, first init the spinner with mock data.
public void initSpinner(){
CalendarNameAdapter exteralCalAdapter = createAdapterWithString(this, "temp calendar");
mExternalSpinner.setAdapter(exteralCalAdapter);
}
public CalendarNameAdapter createAdapterWithString(Context context, String display) {
ArrayList<AgendaLogic.ExternalCalendarInfo> list = new ArrayList<AgendaLogic.ExternalCalendarInfo>();
list.add(new AgendaLogic.ExternalCalendarInfo(-1, display, 0xaabbcc));
CalendarNameAdapter dataAdapter = new CalendarNameAdapter(context,
0, list); //don't care about resource file, since we always use custom file, hence 0
return dataAdapter;
}
When I already load the data I need, I add it to the adapter:
private void setCalendarInfoToSpinner(ArrayList<AgendaLogic.ExternalCalendarInfo> calList, Spinner spinner) {
CalendarNameAdapter adapter = (CalendarNameAdapter) spinner.getAdapter();
adapter.clear();
for (AgendaLogic.ExternalCalendarInfo info: calList)
adapter.add(info);
adapter.notifyDataSetChanged();
}
I ended up answering my own question for who needs it later. The solution is: check in the layout file of the list item. If there is a button, a radio, a checkbox, .etc. Set its focusability to false so that when you tap on the item, the list get the tap, not that child view.
Credit goes to another answer for similar question, but I can't seem to find it now.