GrandDuc GrandDuc - 17 days ago 8
Android Question

Added element doesn't show in RecyclerView after deleting another with swipe

Edit: if anyone is having the same problem in the future it was a pretty easy fix. I used clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) to handle when the entire drag was finished and had forgotten to call it's super-method. That's why it didn't update properly.

Original question:

Here's the entire code: https://github.com/vustav/Ppaaiinntt/tree/master/app/src/main/java/com/decent/rvtest

Everything works fine except when I add an element right after deleting another. It does exist though. If I add another there's a properly sized space between the old list and the new element. I use a string where they add their names before a print and it shows there, and if I drag to change positions of the elements it shows up properly.

My reputation doesn't allow me to post images so an imgur-album will have to do:
http://imgur.com/a/bmb17


  • On the first image there's three elements and the string is printed at the bottom.

  • The second image is after the swipe. Notice the string is updated.

  • The third is after adding another "111". The string is correct but it doesn't show up in the view.

  • The fourth is after adding another. The string is still correct and the new element shows up in the view.

  • The last image is after dragging to change the position of the last two elements. Now everything is fine again.



These are the relevant methods (I think):

protected void add(PictureElement pe){
chain.add(pe);
notifyItemInserted(chain.size()-1);
}

public void remove(int position) {
chain.remove(position);
notifyItemRemoved(position);
}

protected void swap(int from, int to){
chain.swap(from, to);
notifyItemMoved(from, to);
}


Edit: onBindViewHolder, getItemCount and the ViewHolder:

@Override
public int getItemCount() {
return chain.size();
}

@Override
public void onBindViewHolder(PEViewHolder PEViewHolder, int i) {
PictureElement pe = chain.get(i);
PEViewHolder.name.setText(pe.getName());
}

protected static class PEViewHolder extends RecyclerView.ViewHolder {
protected TextView name;

public PEViewHolder(View v) {
super(v);
name = (TextView) v.findViewById(R.id.txtName);
}
}

Answer

Interesting quote on the different notify methods you are using

public final void notifyItemRemoved (int position) Notify any registered observers that the item previously located at position has been removed from the data set. The items previously located at and after position may now be found at oldPosition - 1. This is a structural change event. Representations of other existing items in the data set are still considered up to date and will not be rebound, though their positions may be altered. Parameters position : Position of the item that has now been removed.

public final void notifyItemRangeChanged (int positionStart, int itemCount) Notify any registered observers that the itemCount items starting at position positionStart have changed. Equivalent to calling notifyItemRangeChanged(position, itemCount, null);. This is an item change event, not a structural change event. It indicates that any reflection of the data in the given position range is out of date and should be updated. The items in the given range retain the same identity.

Could you try and comment this block of code and check if it works

//Called by the ItemTouchHelper when the user interaction with an element is over and it also
    // completed its animation
    /*
@Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {

        //update from where the action took place
        mPEAdapter.updateChain(viewHolder.getLayoutPosition());

        //clearView is called after onMove so any drags or swipes are complete
        dragging = false;
        mPEAdapter.setSwipe(false);
    }
*/