Skip to content Skip to sidebar Skip to footer

Wrong Row Deleted From Custom Listview With Spinner

I'm working on app that contains a custom ListView with a remove button that I update from the main activity. I have an issue removing a row from the ListView, although I'm deletin

Solution 1:

The problem is with

holder.spNames.setTag(position); 

and

holder.spNames.setSelection((Integer) holder.spNames.getTag());

As you are setting the tag for name in "onItemSelected()". When you delete the item you remove the item from the list of student, but what about the tag.

Let us say you deleted the item at 0.

Now, when "notifyDataSetChanged()" is called it will repopulate the listview based on the data is available. Now , here

else{
        holder = (ViewHolder) view.getTag();
    }

is getting called. When the i= 0 in getView() you will get the view of the "0 th" index of the previous populated list. Hence, the "(Integer) holder.spNames.getTag()" will point to the previous tag (i.e. 0 of the previous list) . This might be the cause of the issue.

I am posting updated code of

listviewAdapter

publicclassListviewAdapterextendsBaseAdapter
{
public Activity context;
public LayoutInflater inflater;
private ArrayList<Student> studentID;
private String[] studentsNames;
privateboolean isDeleted;
publicListviewAdapter(Activity context, ArrayList<Student> students, String[] names)
{
    super();
    studentID = students;
    studentsNames = names;

    this.context = context;
    this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@OverridepublicintgetCount() {
    return studentID.size();
}

@Overridepublic Student getItem(int position) {
    return studentID.get(position);
}

@OverridepubliclonggetItemId(int position) {
    return position;
}




publicclassViewHolder {
    Spinner spNames, spGrades;
    TextView tvValue;
    Button btnSet, btnRemove;
    int index;
}

@Overridepublic View getView(int i, View view, final ViewGroup viewGroup)
{
    final ViewHolder holder;
    if (view == null) {
        holder = newViewHolder();
        view = inflater.inflate(R.layout.listview_row, null);

        holder.spNames = (Spinner) view.findViewById(R.id.spNames);
        holder.spGrades = (Spinner) view.findViewById(R.id.spGrades);
        holder.tvValue = (TextView) view.findViewById(R.id.tv_Value);
        holder.btnSet = (Button) view.findViewById(R.id.btn_setValue);
        holder.btnRemove = (Button) view.findViewById(R.id.btn_Remove);
        Log.e("IAM", "CALLED");
        view.setTag(holder);
        //holder.spNames.setTag(0);//holder.spGrades.setTag(0);
    }
    else{
        holder = (ViewHolder) view.getTag();
    }
    holder.index=i;
   if(isDeleted){
       holder.tvValue.setText(getItem(holder.index).getName()+ " got " + getItem(holder.index).getGrade()); 
            }
    // pop spinner names
    ArrayAdapter<String> studentsNamesAdapater = newArrayAdapter<String>
            (view.getContext(), android.R.layout.simple_spinner_dropdown_item, studentsNames);
    studentsNamesAdapater.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    holder.spNames.setAdapter(studentsNamesAdapater);

    // pop spinner grades
    String[] grades = newString[101];
    for (intgrade=0; grade < 101; grade++)
        grades[grade] = String.valueOf(grade);

    final ArrayAdapter<String> studentsGradesAdapter = newArrayAdapter<String>
            (view.getContext(), android.R.layout.simple_spinner_dropdown_item, grades);
    studentsGradesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    holder.spGrades.setAdapter(studentsGradesAdapter);


    // select the right spNames index//holder.spNames.setSelection((Integer) holder.spNames.getTag());
    holder.spNames.setSelection(getItem(holder.index).getNameIndex());
    // saving spinner index
    holder.spNames.setOnItemSelectedListener(newAdapterView.OnItemSelectedListener() {
        @OverridepublicvoidonItemSelected(AdapterView<?> parent, View view, int position, long id) {
            //holder.spNames.setTag(position);
            getItem(holder.index).setNameIndex(position);
        }

        @OverridepublicvoidonNothingSelected(AdapterView<?> parent) {

        }
    });

    // select the right spGrades index// holder.spGrades.setSelection((Integer) holder.spGrades.getTag());

    holder.spGrades.setSelection(getItem(holder.index).getGrageIndex());
    // saving spinner index
    holder.spGrades.setOnItemSelectedListener(newAdapterView.OnItemSelectedListener() {
        @OverridepublicvoidonItemSelected(AdapterView<?> parent, View view, int position, long id) {
           // holder.spGrades.setTag(position);
            getItem(holder.index).setGrageIndex(position);
        }

        @OverridepublicvoidonNothingSelected(AdapterView<?> parent) {

        }
    });

    // set (variable and textview)
    holder.btnSet.setTag(i);
    holder.btnSet.setOnClickListener(newView.OnClickListener() {
        @OverridepublicvoidonClick(View v) {
            // update studentID//final int position = getRowPosition(v);intposition= (Integer) v.getTag();
           // Student tmp = new Student(holder.spNames.getSelectedItem().toString(), Integer.valueOf(holder.spGrades.getSelectedItem().toString()));// studentID.set(position, tmp);
            getItem(position).setName(holder.spNames.getSelectedItem().toString());
            getItem(position).setGrade(Integer.valueOf(holder.spGrades.getSelectedItem().toString()));
            holder.tvValue.setText(getItem(position).getName()+ " got " + getItem(position).getGrade());
            //((MainActivity) context).updateStatus(position);
        }
    });


    // remove row
    holder.btnRemove.setTag(i);
    holder.btnRemove.setOnClickListener(newView.OnClickListener() {
        @OverridepublicvoidonClick(View v) {
            //final int position = getRowPosition(v);intposition= (Integer) v.getTag();
            studentID.remove(position);
            notifyDataSetChanged();
            //((MainActivity) context).adapter.notifyDataSetChanged();
            isDeleted=true;
            // for debugStringdStatus="Vector size: " + studentID.size() + "\n";
            for (intindex=0; index < studentID.size(); index++)
                dStatus += studentID.get(index).name + " " + studentID.get(index).grade + "\n";
            Toast.makeText(v.getContext(), dStatus, Toast.LENGTH_SHORT).show();
        }
    });

    return view;
}

publicvoidprintS() {
    for (inti=0; i <studentID.size(); i++) {
        Log.e("NAME", ""+studentID.get(i).getName());
        Log.e("GRADE", ""+studentID.get(i).getGrade());
    }
}
}

and

Student

publicclassStudent {
public String name;
publicint grade;
privateint nameIndex;
privateint grageIndex;

publicStudent()
{
    name = "";
    grade = 0;
}

publicStudent(String _name, int _grade)
{
    name = _name;
    grade = _grade;
}

public String getName() {
    return name;
}

publicvoidsetName(String name) {
    this.name = name;
}

publicintgetGrade() {
    return grade;
}

publicvoidsetGrade(int grade) {
    this.grade = grade;
}

publicintgetNameIndex() {
    return nameIndex;
}

publicvoidsetNameIndex(int nameIndex) {
    this.nameIndex = nameIndex;
}

publicintgetGrageIndex() {
    return grageIndex;
}

publicvoidsetGrageIndex(int grageIndex) {
    this.grageIndex = grageIndex;
}
}

Solution 2:

I suggest that you use setOnItemClickListener method on your list view. There are some advantages :

  • You won't have to create a new OnClickListener each time your item is rendered
  • You have a direct access to the position of the view and to the view itself : onItemClick(AdapterView<?> parent, View view, int position, long id)

You can then use that position to remove you item from your adapter.

Solution 3:

Basically this problem happens because of View recycling. Add these two methods to your adapter class

@OverridepublicintgetViewTypeCount() {
     return studentID.size() + 1;
 }

 @OverridepublicintgetItemViewType(int position) {
     return position;
 }

Here is link which explains why you have to add these two methods. Getting an issue while checking the dynamically generated checkbox through list view

I hope it helps!

Solution 4:

you need to set tag as position for button each time you create, then inside onclick, get the tag, it will return you the correct position

inside your getView

holder.btnRemove = (Button) view.findViewById(R.id.btn_Remove);
holder.btnRemove.setTag(position);

and then onClick(View view)

int position = (Integer) ((Button) view).getTag();
//remove item from position, and do the stuff here

then try to remove the item from position.

alternate solution:

Solution 5:

simply get the position of the item to be deleted on click and then remove it from your arraylist using arraylist.remove(position) and then call notifyDataSetChanged.

Post a Comment for "Wrong Row Deleted From Custom Listview With Spinner"