Reputation: 1116
I have an expandable list view where users can click a button to "save" a record. However, the listviews of my expandable listview seem to populate properly (the titles are different). But when a user "saves" element 1 it also saves elements 4,7,10,...n+3 (I know this because the view is set to invisible once it's saved). If you look below, I think I am recycling elements properly using the setTag() method in my getChildView() method.
I put some logging in my getChildView() for testing whether or not the view is cached is or drawn for the first time. The first two views are drawn and the rest are cached.
So my problem, as stated before is that when someone interacts with an element on the expandablelistview other elements are changed accordingly.
Here is my adapter:
public class SurveyListAdapter extends BaseExpandableListAdapter {
private final SparseArray<Group> groups;
public LayoutInflater inflater;
private Context appContext;
public String TAG = "SurveyListAdapter";
private static SparseArray<SparseArray<Survey>> results = new SparseArray<SparseArray<Survey>>();
//private static SparseArray<ArrayList<Boolean>> rowSubmitted = new SparseArray<ArrayList<Boolean>>();
public SurveyListAdapter(Context context, SparseArray<Group> groups) {
this.appContext = context;
this.groups = groups;
for(int i = 0;i<groups.size();i++) {
Log.d(TAG, "Creating group: " + i);
results.put(i, new SparseArray<Survey>());
}
//inflater = context.getLayoutInflater();
this.inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
}
@Override
public Survey getChild(int groupPosition, int childPosition) {
//Log.d("getChild", "Group: " + groupPosition + "\tChild: " + childPosition);
return this.groups.get(groupPosition).children.get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
//return Long.parseLong(this.groups.get(groupPosition).children.get(childPosition));
return childPosition;
}
public Survey getIdOfChild(int groupPosition, int childPosition) {
return this.groups.get(groupPosition).children.get(childPosition);
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View row = convertView;
SurveyViewHolder svh;
Survey child = getChild(groupPosition, childPosition);
if (row == null) {
row = inflater.inflate(R.layout.list_view_survey_row, parent, false);
svh = new SurveyViewHolder();
svh.title = (TextView) row.findViewById(R.id.tvSurveyTitle);
svh.rg = (RadioGroup) row.findViewById(R.id.radioShared);
svh.interest = (CheckBox) row.findViewById(R.id.checkBoxInterest);
svh.privacy = (CheckBox) row.findViewById(R.id.checkBoxPrivacy);
svh.rating = (RatingBar) row.findViewById(R.id.ratingBar);
svh.submit = (Button) row.findViewById(R.id.btnSubmitRow);
row.setTag(svh);
Log.d(TAG, "Built from scratch");
} else {
Log.d(TAG, "Cached");
svh = (SurveyViewHolder) row.getTag();
}
svh.title.setText(child.getTitle());
svh.children = child.getTitle();
svh.submit.setOnClickListener(new CustomOnClickListener(row, svh, groupPosition, childPosition));
//this.registerClickListeners(groupPosition, childPosition, convertView);
return row;
}
@Override
public int getChildrenCount(int groupPosition) {
return groups.get(groupPosition).children.size();
}
@Override
public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}
@Override
public int getGroupCount() {
return groups.size();
}
@Override
public void onGroupCollapsed(int groupPosition) {
super.onGroupCollapsed(groupPosition);
}
@Override
public void onGroupExpanded(int groupPosition) {
super.onGroupExpanded(groupPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.xplist_view_survey_group, null);
}
Group group = (Group) getGroup(groupPosition);
((TextView) convertView).setText(group.string);
//((CheckedTextView) convertView).setChecked(isExpanded);
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
public SparseArray<SparseArray<Survey>> getResults() {
return results;
}
public void emptyResults() {
for(int i=0; i<results.size();i++) {
for(int j=0;j<results.get(i).size();j++) {
results.get(i).remove(j);
}
}
}
public class SurveyViewHolder {
public TextView title;
public RadioGroup rg;
public RatingBar rating;
public CheckBox interest;
public CheckBox privacy;
public Button submit;
public String children;
}
public class CustomOnClickListener implements View.OnClickListener {
private View row;
private SurveyViewHolder svh;
private int group;
private int child;
public CustomOnClickListener(View r, SurveyViewHolder s, int g, int c) {
this.row = r;
this.svh = s;
this.group = g;
this.child = c;
}
@Override
public void onClick(View v) {
boolean addIt = false;
try{
if(results.get(this.group).get(this.child, null) == null) {
addIt = true;
}
} catch(NullPointerException e) {
Log.d(TAG, "NPE");
addIt = true;
}
if (addIt) {
if (svh.rg.getCheckedRadioButtonId() > 0 && svh.rating.getRating() > 0) {
Boolean[] reasons = new Boolean[]{false, false, false};
// Hide the view
this.row.setVisibility(View.INVISIBLE);
// Start saving the record
Survey s = new Survey(svh.title.getText().toString());
s.setRating(svh.rating.getRating());
if (svh.privacy.isChecked()) {
reasons[0] = true;
} else if (svh.interest.isChecked()) {
reasons[1] = true;
}
s.setReason(reasons);
results.get(this.group).put(this.child, s);
Toast.makeText(appContext, "Record Saved", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(appContext, "You must give a rating and shared status", Toast.LENGTH_SHORT).show();
}
} else {
Log.d(TAG, "Record already saved");
this.row.setVisibility(View.INVISIBLE);
}
}
}
}
Thank you for any help, I'm really struggling with this problem!
Upvotes: 2
Views: 1041
Reputation: 2019
You set visibility to row in CustomOnClickListener
and then reuse this invisible View
for new items.
Suppose you pressed Save
on second item. It is invisible now. Then if you scroll the second item's view would be reused for new item. Let say that it would be the item 5. Of course you see that 5'th item is hidden, because it is the same View
as it was for second item.
Try to update visibility of row inside getChildView()
in the same place where you update titles.
Upvotes: 2