I don't see any association between the ViewHolder respectivly the classes you use for it and the convertView itself, which means the ViewHolder doesn't get attached to the ViewGroup. E.g.
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(getLayoutResourceId(), null);
holder = new ViewHolder();
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
And remember to set the values also when the convertView is not null. The calls to getChildView are subsequently repeated for all itmes in your list. Example continued:
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
String childText = (String) getChild(groupPosition, childPosition);
int itemType = getChildType(groupPosition,childPosition);
switch (itemType) {
case 0:
return getChildViewDistanza(groupPosition, childPosition, isLastChild, convertView, parent);
break;
case 1:
....
}
return convertView;
}
public View getChildViewDistanza(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
DistanzaViewHolder distanzaViewHolder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.listview_item_filter_descrizione, null);
DistanzaViewHolder distanzaViewHolder = new DistanzaViewHolder();
convertView.setTag(distanzaViewHolder);
}
else {
distanzaViewHolder = convertView.getTag();
}
descrizioneViewHolder.etDescrizione = (EditText) convertView.findViewById(R.id.etDescrizione);
return convertView;
}
if you would like to get rid of the repetative element concerning layout - inflating and setting the tag, you could easily write a method for this, too, if you use a common base class amongs your ViewHolder:
protected View inflateLayoutAndSetTag(int resourceID, BaseViewHolder holder) {
LayoutInflater inflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View convertView = inflater.inflate(resourceID) , null);
convertView.setTag(holder) );
return convertView;
}
and call it as:
if (convertView == null) {
DistanzaViewHolder distanzaViewHolder = new DistanzaViewHolder();
convertView = inflateLayoutAndSetTag(R.layout.listview_item_filter_descrizione, distanzaViewHolder);
}
actually you can even do things such as
protected <TViewHolder> Pair<View, TViewHolder> getViewHolderAndConvertView(View convertView, int resourceID, TViewHolder dummy) { /** TViewHolder is a type - parameter that is actually unused, just needed for the instanziation of the right type and the pair - type ***/
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resourceID, null);
TViewHolder viewHolder = TViewHolder.class.newInstance();
convertView.setTag(viewHolder);
}
else {
viewHolder = convertView.getTag();
}
return new Pair<View, TViewHolder>(convertView, viewHolder);
}
and call this as e.g.:
Pair<View, DistanzaViewHolder> pair = getViewHolderAndConvertView(convertView, R.layout.listview_item_filter_descrizione, (DistanzaViewHolder) null);
DistanzaViewHolder viewHolder = pair.second;
convertView = pair.first;
removing all of that repetativ code. But's that's a little bit out of scope of this question. ;)