Android ListView repeating modified list items

I have a ListView with some list items in. Each item has a delete button, which activates another layer on top of the list item to appear with the text that it has been deleted, as see in the delete onClickListener in the following code.

These activated overlays repeat themselves every so often (like every 8 list items), so I guess android is recycling them somehow… How can I make it so that this problem doesn’t happen anymore?

public View getView(int i, View view, ViewGroup viewGroup) {
    final AnnouncementHolderItem holder;
    final View finalView = view;
    Item curr = getItem(i);
    if(view == null){
        LayoutInflater inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.list_item, null);
        holder = new HolderItem(view);
        view.setTag(holder);
    } else {
        holder = (HolderItem) view.getTag();
    }
    holder.title.setText(curr.getTitle());
    holder.course.setText(curr.getName());
    holder.marker.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(activity, "Item starred!", Toast.LENGTH_SHORT).show();
        }
    });
    holder.delete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ((LinearLayout) finalView.findViewById(R.id.bottomLayer)).setVisibility(View.INVISIBLE);
            LinearLayout delete = (LinearLayout)finalView.findViewById(R.id.deleteLayer);
            delete.setVisibility(View.VISIBLE);
        }
    });
    holder.undelete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Reverse of the delete + a toast message
        }
    });
    return finalView;
}

And the list item is a FrameLayout, with the deleted layer on top (default invisible) and the info about the item below it.

Answer

You’re exactly right: the listview is recycling views. You need some means of keeping track of which items have been “deleted” outside the control of the listview. In your case, it sounds like a simple array would do the trick.

Below is an example of code I’ve used to do the same thing. In this case, it’s a checkbox, where all checkboxes are initially unchecked.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.dialog_checkbox_item, null);
        holder = new ViewHolder();
        holder.checkbox = (CheckBox)convertView.findViewById(R.id.dialog_checkbox);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder)convertView.getTag();
        if (checkedArray[position] == true)
            holder.checkbox.setChecked(true);
        else
            holder.checkbox.setChecked(false);
    }
    holder.checkbox.setText((CharSequence) mData.get(position));
    return convertView;
}
Source: stackoverflow
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .