Arrayadapter thinks a list of 45 items only holds 8 repeating items

368 Views Asked by At

I have a listview backed by custom arrayadapterI wrote. Every listview item contains a textview and a seekbar. The idea behind this is that a user is supposed to be able to move every seekbar and the application stores the value of that seekbar (so the seekbars can be restored to their proper values if the user exits the fragment). These values are stored in a hashmap where the key is the name of the competence (AKA the textview of the element)

My issue with this is this: The listview holds 45 elements, however, after the 8th element, my adapter seems to think the listview is back at the starting point. For example: if I move the seekbar of the 9th element and then proceed to scroll up, the 1st element would them have the value that I gave the 9th element. The listview itself does get populated correctly (or so it seems anyway) though as the textviews of every element are different.

Here is my custom arrayadapter:

public class CompetenceJudgementListAdapter extends ArrayAdapter<String[]> {

private Context mContext;
private ArrayList mData;
int mLayoutResourceId;
ArrayList<CompetenceItem> mCompetenceItemList;
HashMap<String, Integer> valueList;

public CompetenceJudgementListAdapter(Context context, int resource, ArrayList<String[]> data) {
    super(context, resource, data);
    mContext = context;
    this.mLayoutResourceId = resource;
    mData = data;
    mCompetenceItemList = new ArrayList<CompetenceItem>();
    valueList = new HashMap<String, Integer>();
}

public ArrayList<String[]> getCompetenceItemData(){
    ArrayList<String[]> list = new ArrayList<String[]>();
    for(CompetenceItem item : mCompetenceItemList){
        String[] data = new String[3];
        data[0] = (String) item.title.getText();
        if(valueList.get(item.competence_id) != null){
            data[1] = String.valueOf(valueList.get(item.competence_id).toString());
        }
        data[2] = item.competence_id;
        list.add(data);
    }
    return list;
}

@Override
public int getCount() {
    return mData.size();
}

@Override
public String[] getItem(int position) {
    return null;
}

@Override
public long getItemId(int position) {
    return 0;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent){
    View row = convertView;
    CompetenceItem competenceItem = null;
    String[] measurementData = (String[]) mData.get(position);
    String c_title = measurementData[0];
    String c_id = measurementData[2];
    if (row == null) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        row = inflater.inflate(mLayoutResourceId, parent, false);
        competenceItem = new CompetenceItem();
        mCompetenceItemList.add(competenceItem);
        competenceItem.title = (TextView) row.findViewById(R.id.textview_header_competence_name);
        competenceItem.seekbar = (SeekBar) row.findViewById(R.id.seekbar_competence);
        competenceItem.seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            Integer newProgress = 0;
            String competenceId;

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            }

            private SeekBar.OnSeekBarChangeListener init(String var) {
                competenceId = var;
                return this;
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                newProgress = seekBar.getProgress();
                valueList.put(competenceId, newProgress);
            }
        }.init(c_title));
        row.setTag(competenceItem);

    } else {
        competenceItem = (CompetenceItem) row.getTag();
    }

    competenceItem.title.setText(measurementData[0]);
    competenceItem.competence_id = measurementData[2];
    int max = SharedData.COMPETENCE_JUDGEMENT_MAX_VALUE.getIntValue();
    competenceItem.seekbar.setMax(max);
    if(measurementData[1] != null){
        String competenceValue = measurementData[1];
        competenceItem.seekbar.setProgress(Integer.parseInt(competenceValue));
    }else{
        competenceItem.seekbar.setProgress(0);
    }
    if((valueList.get(competenceItem.title.getText() )!= null)){
    competenceItem.seekbar.setProgress(valueList.get(competenceItem.title.getText()));
    }
    return row;
}

static class CompetenceItem{
    TextView title;
    SeekBar seekbar;
    String competence_id;
}
2

There are 2 best solutions below

2
On BEST ANSWER
 if (row == null) {

        LayoutInflater inflater = LayoutInflater.from(mContext);
        row = inflater.inflate(mLayoutResourceId, parent, false);
        competenceItem = new CompetenceItem();
        mCompetenceItemList.add(competenceItem);
        competenceItem.title = (TextView) row.findViewById(R.id.textview_header_competence_name);
        competenceItem.seekbar = (SeekBar) row.findViewById(R.id.seekbar_competence);
        row.setTag(competenceItem);

    } else {
        competenceItem = (CompetenceItem) row.getTag();
    }
     competenceItem.seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            Integer newProgress = 0;
            String competenceId;

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            }

            private SeekBar.OnSeekBarChangeListener init(String var) {
                competenceId = var;
                return this;
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                newProgress = seekBar.getProgress();
                valueList.put(competenceId, newProgress);
            }
        }.init(c_title));

This should work i think.Since this listener is same for recycled views.

0
On

its caused by recycling your view

if (row == null) {
   //******
}else {
    competenceItem = (CompetenceItem) row.getTag(); //here you are doing the recycle
}
// here you must reset your seekbar