2

I'm assuming I am just not understanding the RecyclerView properly, however I am having a problem with adding an item after it's been deleted.

My view consists of a card layout with some text and two image views.

The two image views are stacked, and when the card is selected, the first view is flipped then, the second is flipped in and set to visible. When an item is selected the user can edit or delete it.

When it is deleted, and then brought back with an undo action, the imageview remains flipped. (Even though when I delete it I flip it back before removing). I have included an example.

Also if I add multiple new entries at once, some of them will have the flipped imageview. So what am I doing wrong?

The Adapter

public void unSelect(List<Message> messages) {
    for (Message message : messages) {
        if (message.isSelected()) {
            int position = mMessages.indexOf(message);
            Message m = mMessages.get(position);
            m.setSelected(false);
            m.setWasSelected(true);
            notifyItemChanged(position);
        }
    }
}

public int add(Message message) {
    int position = 0;
    if (message != null) {
        message.save();
        mMessages.add(message);
        Collections.sort(mMessages);
        Collections.reverse(mMessages);
        position = mMessages.indexOf(message);
        notifyItemInserted(position);
    }
    return position;
}

public void delete(Message message) {
    int position = mMessages.indexOf(message);
    if (position !=  -1) {
        message.setSelected(false);
        message.setWasSelected(false);
        message.delete();
        mMessages.remove(message);
        notifyItemRemoved(position);
    }
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Message message = mMessages.get(position);

    if (message.isSelected()) {
        holder.iconReverse.setVisibility(View.VISIBLE);
        holder.selected = true;
    } else if (message.wasSelected()) {
        holder.iconReverse.setVisibility(View.VISIBLE);
        holder.selected = false;
        holder.animator.reset(true);
        mMessages.set(position, message);
    }
}

The Viewholder

    ImageView icon, iconReverse, repeat;
    TextView recipient, date, message, recipientNum;

    IconAnimator animator;

    boolean hasExtraRecipient;
    boolean selected;

    public ViewHolder(View itemView) {
        super(itemView);
        icon = (ImageView) itemView.findViewById(R.id.icon);
        iconReverse = (ImageView) itemView.findViewById(R.id.icon_reverse);
        recipient = (TextView) itemView.findViewById(R.id.contact);
        recipientNum = (TextView) itemView.findViewById(R.id.recipient_num);

        animator = new IconAnimator(mContext, icon, iconReverse);
    }

    @Override
    public void onClick(final View v) {
        recipientNum.setVisibility(View.INVISIBLE);
        animator.start(selected);
        mMessages.get(getAdapterPosition()).setSelected(selected = !selected);
        if (mListener != null) {
            mListener.cardSelected(v, mMessages.get(getAdapterPosition()));
        }
    }

Here

jordond
  • 367
  • 4
  • 15
  • Please post your adapter code. – Rami Aug 16 '15 at 08:01
  • Added relevant portions of the adapter and the view holder. The IconAnimator class is a class that takes the two image views. Animates the first one by flipping it 90 degrees, then when that ends it takes the second and does the same. – jordond Aug 16 '15 at 17:28

1 Answers1

1

You forgot to handle the case when the item isn't selected (message.isSelected() == false ) and wasn't selected ( message.wasSelected() == false ). Otherwise the recycling mechanism of the RecyclerView will cause this problem.

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Message message = mMessages.get(position);

    if (message.isSelected()) {
        holder.iconReverse.setVisibility(View.VISIBLE);
        holder.selected = true;
    } else if (message.wasSelected()) {
        holder.iconReverse.setVisibility(View.VISIBLE);
        holder.selected = false;
        holder.animator.reset(true);
        mMessages.set(position, message);
    } else {
       // add the necessary stuff 
       hereholder.selected = false;
       ....
    }
}
Rami
  • 7,879
  • 12
  • 36
  • 66
  • Yes thank you, I feel like an idiot now. I previously tried that, but that was before I modified my animator code, and it caused even more problems. I forgot to try it again after I optimized my animator. Fresh eyes was all I needed, my tired brain couldn't think. Thanks. – jordond Aug 16 '15 at 19:16