I'm trying to realize a layout with an ExpendableListView. There are 4 Group Elements and for each Group 2 Children. The first Group Element does have 0 Children.
G
G
C
C
G
C
C
G
C
C
Every Group Element has 2 TextViews, 1 ImageView and 1 Switch. Every Child Element has 2 TextViews and 1 SeekBar.
The Adapter contains 2 Holder. One for the Groupviews and one for the Childviews.
On the Group Layer everything works as intented.
But on the Child Layer the different ChildViews are interdependend. For example setting the SeekBar of Group Element3/Child Element1 sets the SeekBar of Group Element1/Child Element0 too.
I do understand the problem has something to do with missing uniques of the views and view handling(optimizing) by Android.
Here is the getChildView method:
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final int tempgroupPos = groupPosition;
final int tempchildPos = childPosition;
ChildViewHolder cviewHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.interfaces_listrow_details_intervall, null);
cviewHolder = new ChildViewHolder();
cviewHolder.tvb = (TextView) convertView.findViewById(R.id.interfaces_child_intervall_textbig);
cviewHolder.tvs = (TextView) convertView.findViewById(R.id.interfaces_child_intervall_textexplanation);
cviewHolder.sb = (SeekBar) convertView.findViewById(R.id.interfacesSeekBar);
cviewHolder.sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
int getPosition = (Integer) seekBar.getTag();
clist.get(tempgroupPos).get(tempchildPos).setProgress(seekBar.getProgress());
// do stuff
notifyDataSetChanged();
}
});
convertView.setTag(cviewHolder);
convertView.setTag(R.id.interfaces_child_intervall_textbig, cviewHolder.tvb);
convertView.setTag(R.id.interfaces_child_intervall_textexplanation, cviewHolder.tvs);
convertView.setTag(R.id.interfacesSeekBar, cviewHolder.sb);
} else {
cviewHolder = (ChildViewHolder) convertView.getTag();
}
cviewHolder.sb.setTag(groupPosition);
cviewHolder.sb.setProgress(clist.get(groupPosition).get(childPosition).getProgress());
cviewHolder.tvb.setText(clist.get(groupPosition).get(childPosition).getBigText());
cviewHolder.tvs.setText(clist.get(groupPosition).get(childPosition).getSmallTextActivated());
return convertView;
}
If you need any other part of the code or other informations please ask.
I looked into these Question/Answers but they did not really help me personally.
OK. Besides I am not really sure why this approach won't work I looked again on the posted links to Q/A. I've choosed this one
Android - Expandable ListView - using ViewHolder for optimization
and followed everything exactly. Now it works that way. I focused to much on my first choosen example. Thank you. My code is working now. Here is the code for others to refer.
ChildViewHolder:
// https://stackoverflow.com/questions/22583689/android-expandable-listview-using-viewholder-for-optimization
static class ChildViewHolder {
private HashMap<Integer, View> storedViews = new HashMap<Integer, View>();
public ChildViewHolder addView(View view)
{
int id = view.getId();
storedViews.put(id, view);
return this;
}
public View getView(int id)
{
return storedViews.get(id);
}
}
getChildView Method:
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final int tempgroupPos = groupPosition;
final int tempchildPos = childPosition;
View row = convertView;
if (row == null)
{
row = inflater.inflate(R.layout.interfaces_listrow_details_intervall, parent, false);
TextView tvb = (TextView) row.findViewById(R.id.interfaces_child_intervall_textbig);
TextView tvs = (TextView) row.findViewById(R.id.interfaces_child_intervall_textexplanation);
SeekBar sb = (SeekBar) row.findViewById(R.id.interfacesSeekBar);
ChildViewHolder cholder = new ChildViewHolder();
cholder.addView(tvb);
cholder.addView(tvs);
cholder.addView(sb);
row.setTag(cholder);
}
ChildViewHolder cholder = (ChildViewHolder) row.getTag();
TextView tvb = (TextView) cholder.getView(R.id.interfaces_child_intervall_textbig);
TextView tvs = (TextView) cholder.getView(R.id.interfaces_child_intervall_textexplanation);
SeekBar sb = (SeekBar) cholder.getView(R.id.interfacesSeekBar);
sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
Globals g = Globals.getInstance();
clist.get(tempgroupPos-1).get(tempchildPos).setProgress(seekBar.getProgress());
// do something
notifyDataSetChanged();
}
});
tvb.setText(clist.get(groupPosition-1).get(childPosition).getBigText());
tvs.setText(clist.get(groupPosition-1).get(childPosition).getSmallTextActivated());
sb.setProgress(clist.get(groupPosition-1).get(childPosition).getProgress());
return row;
}