RecyclerView does not update after removing an item [duplicate]
Asked Answered
S

7

7

I have a RecyclerView horizontal image slider at the bottom of a fragment. The top of the fragment shows some details. Once the user clicks on the images at the bottom, the idea is to remove that image from the image slider and display its information in the fragment. Now the information shows up but the image does not gets removed from the RecyclerView. Here is what I have coded in the Onclick of the outermost layout. I have tried all the related answers that I could find but nothing worked. They all are in the code. Please let me know what am I doing wrong or what is missing.

holder.itemRowRelativeLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (isFiltering) {
                mItemList.clear();
                mItemList.addAll(mOriginalItemList);
                mItemList.remove(position);// At this point mItemList holds the correct. That is all the images but not the one that was clicked. 

                notifyItemRemoved(position); //solution 1
                notifyItemRangeRemoved(position, getItemCount()); // solution 2
                notifyItemRangeRemoved(0, getItemCount()); // solution 3
                notifyDataSetChanged();//solution 4
            }
        }
    });

Full Code of the adapter

public class ImageGallery16X9Adapter<T extends GalleryItem> extends RecyclerView.Adapter<ImageGallery16X9Adapter.GalleryItemViewHolder> {

public enum GalleryMode {
    All_SAME,
    FIRST_DIFFERENT
}

private Context mContext;
private BasePresenter mPresenter;
private List<T> mItemList;
private List<T> mOriginalItemList;
private GalleryItem mFirstItem;
private GalleryMode mGalleryMode;
private int deviceWidth, itemWidth, marginSingle, marginDouble;
private boolean isFiltering;

public ImageGallery16X9Adapter(Context context, BasePresenter presenter, GalleryMode galleryMode, List<T> itemList, GalleryItem firstItem, boolean isFiltering) {
    mContext = context;
    mPresenter = presenter;
    mGalleryMode = galleryMode;
    mItemList = new ArrayList<>(itemList);
    mOriginalItemList = new ArrayList<>(itemList);
    mFirstItem = firstItem;
    deviceWidth = CommonUtils.getDeviceWidth((Activity) mContext);
    itemWidth = (int) (deviceWidth * 0.9);
    marginDouble = (int) (deviceWidth * 0.05);
    marginSingle = (int) (deviceWidth * 0.025);
    this.isFiltering = isFiltering;
}

@Override
public GalleryItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return new GalleryItemViewHolder(LayoutInflater.from(parent.getContext()).
            inflate(R.layout.row_image_gallery_16x9_item, parent, false));
}

@Override
public void onBindViewHolder(GalleryItemViewHolder holder, final int position) {
    RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) holder.itemRowRelativeLayout.getLayoutParams();
    RelativeLayout.LayoutParams rlParams = (RelativeLayout.LayoutParams) holder.itemImageView.getLayoutParams();
    layoutParams.width = itemWidth;
    rlParams.height = (int) (layoutParams.width * Constant.HEIGHT_FACTOR_16X9);

    if (position == 0) {
        layoutParams.leftMargin = marginDouble;
        layoutParams.rightMargin = 0;
        if (mGalleryMode == GalleryMode.FIRST_DIFFERENT) {
            holder.itemTitle.setVisibility(View.VISIBLE);
            holder.itemTitle.setText(mFirstItem.getItemTitle());
            if (mFirstItem.getItemImage() != null) {
                Picasso.with(MyApplication.getAppContext()).load(mFirstItem.getItemImage()).fit().placeholder(R.drawable.error_image).error(R.drawable.error_image).into(holder.itemImageView);
            } else {
                Picasso.with(MyApplication.getAppContext()).load(R.drawable.error_image).placeholder(R.drawable.error_image).error(R.drawable.error_image).fit().into(holder.itemImageView);
            }
            holder.itemDescription.setText(mFirstItem.getItemDescription());
        }
    } else {
        if (mGalleryMode == GalleryMode.FIRST_DIFFERENT) {
            if (position == mItemList.size()) {
                layoutParams.rightMargin = marginDouble;
            } else {
                layoutParams.rightMargin = 0;
            }
        } else {
            if (position == mItemList.size() - 1) {
                layoutParams.rightMargin = marginDouble;
            } else {
                layoutParams.rightMargin = 0;
            }
        }
        layoutParams.leftMargin = marginSingle;
    }

    int itemPosition = position;
    if (mGalleryMode == GalleryMode.FIRST_DIFFERENT && position > 0) {
        itemPosition = position - 1;
        T item = mItemList.get(itemPosition);
        holder.itemTitle.setVisibility(View.GONE);
        holder.itemDescription.setText(item.getItemDescription());
        Picasso.with(mContext).load(item.getItemImage()).fit().placeholder(R.drawable.error_image).error(R.drawable.error_image).into(holder.itemImageView);

    } else if (mGalleryMode == GalleryMode.All_SAME) {
        T item = mItemList.get(itemPosition);
        holder.itemTitle.setVisibility(View.GONE);
        holder.itemDescription.setText(item.getItemDescription());
        Picasso.with(mContext).load(item.getItemImage()).fit().placeholder(R.drawable.error_image).error(R.drawable.error_image).into(holder.itemImageView);
    }

    holder.itemRowRelativeLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mGalleryMode == GalleryMode.FIRST_DIFFERENT) {
                if (position == 0) {
                    mPresenter.onItemClicked(mFirstItem);
                } else {
                    mPresenter.onItemClicked(mItemList.get(position - 1));
                }
            } else {
                mPresenter.onItemClicked(mItemList.get(position));
                if (isFiltering) {
                    mItemList.clear();
                    mItemList.addAll(mOriginalItemList);
                    mItemList.remove(position);

                    notifyItemRemoved(position); //solution 1
                    notifyItemRangeRemoved(position, getItemCount()); // solution 2
                    notifyItemRangeRemoved(0, getItemCount()); // solution 3
                    notifyDataSetChanged();//solution 4
                }
            }
        }
    });
}

@Override
public int getItemCount() {
    if (mGalleryMode == GalleryMode.FIRST_DIFFERENT)
        return mItemList.size() + 1;
    else
        return mItemList.size();
}


static class GalleryItemViewHolder extends RecyclerView.ViewHolder {
    private final TextView itemDescription, itemTitle;
    private final ImageView itemImageView, itemFavoriteImageView;
    private final RelativeLayout itemRowRelativeLayout;

    public GalleryItemViewHolder(View itemView) {
        super(itemView);
        itemRowRelativeLayout = (RelativeLayout) itemView.findViewById(R.id.rl_gallery_item_row);
        itemImageView = (ImageView) itemView.findViewById(R.id.img_gallery_item);
        itemFavoriteImageView = (ImageView) itemView.findViewById(R.id.img_gallery_item_favorite);
        itemTitle = (TextView) itemView.findViewById(R.id.txt_gallery_item_name);
        itemDescription = (TextView) itemView.findViewById(R.id.txt_gallery_item_description);
    }
}

}

Superfluous answered 31/7, 2017 at 10:24 Comment(5)
show full adapter code,Apartment
Please see this link.. #26077465Revolutionary
Please check if this method is called or not when you click the outermost layer. (Use logging to check)Impaste
@MohdSaquib I have seen it already. Didn't worked for me.Superfluous
@Impaste Yes I did tried that. My list is having the correct item set. Only the recyclerview wont update and reflect the new items.Superfluous
K
31

You need to use this 3 lines to make it work

mItemList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mItemList.size());
Krystakrystal answered 31/7, 2017 at 10:54 Comment(5)
This have some issue, on a button click I am changing its background drawable (green -> red) and then executing these three lines. But what happens is that when I scrolled the old removed layout started showing in some places. :(Krystakrystal
have you tried overriding this two methods? Override public int getItemViewType(int position) { return position; } Override public long getItemId(int position) { return position; }Krystakrystal
@Krystakrystal this behaviour is cause because recycler-view reuse the view and onBindView Holder is called when the view is not on memory any more, so you need to set for each row the colour of your preference.Desired
@jaydeeppipaliya Is there any similar code available for notifyItemMoved(fromPosition, to Position) ?Misspell
Hi I have an issue wherein after deleting an item I all the next edit text filled are being set to empty and after deleting another item from recyclerview I am getting all the data again. I am using these 3 lines for deleting items.Trumpetweed
N
2
private void removerecyclerItem(DraftStoriesPojo list) {
        int current_position = allStoriesPojoList.indexOf(list);
        allStoriesPojoList.remove(current_position);
        notifyItemRemoved(current_position);
        notifyItemRangeChanged (current_position, getItemCount());
    }
Nicolanicolai answered 19/6, 2018 at 9:5 Comment(0)
V
1

Declare a method in your custom RecylerView.Adapter like below:

public void deleteData(int position) {
    recordingItems.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(position, recordingItems.size());
}

and from MainActivity call:

adapter.deleteData(position);
Vassallo answered 26/5, 2019 at 10:46 Comment(0)
S
0

In order to have your code working you need to change Adapter constructor implementation as follows:

    public RecyclerViewAdapter(Context context, List<Model> model) {
    this.context = context;
    this.model = model;
}

Then in onActivityResult do like this:

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 4) {
        listModel.clear();
        listModel.addAll(repository.consDataBase(context));
        recyclerViewAdapter.notifyDataSetChanged();
    }
}
Squirmy answered 31/7, 2017 at 10:27 Comment(1)
ouch! that hurtMerrile
S
0

No need to do so much complicated things there,simply remove and notify

holder.itemRowRelativeLayout.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (isFiltering) {
            mItemList.remove(position);
            notifyItemRemoved(position);
        }
    }
});
Smegma answered 31/7, 2017 at 10:35 Comment(6)
I have to maintain an original list of items because I have to display all the other images except the one clicked. I have tried this solution. Its mention in my code. It has not worked for me.Superfluous
no need to do mItemList.clear(),mItemList.addAll(mOriginalItemList) these thingsSmegma
How am I going to get the complete item set once i have removed it from the main list. That is why I am maintaining another list that has all the items. These 2 lines have a proper reason to be there. Please read the information I have given in the question carefully.Superfluous
have you tried the solution. You are only removing one item not the entire list so why you need to clear and add the entire list again :/.Smegma
I have tried all the solutions I have posted. I have mentioned this in the post. And you are not able to understand the scenario. Consider the second time a user clicks on an image. This time I've to add the 1st clicked item back to list and then remove the 2nd clicked item. So I am removing all the items and adding them back again and then removing the 2nd clicked item. If you still don't understand try to implement the same yourself instead of commenting.Superfluous
oh now i got it, previously removed item should be there oh okSmegma
D
0

Only add these two lines

mItemList.remove(position);
notifyDataSetChanged();
Diadelphous answered 31/7, 2017 at 10:44 Comment(1)
notifyDataSetChanged will break all RecyclerView conceptHoar
K
-1

You need to use these lines to make it work

mItemList.remove(position);
notifyDataSetChanged();
Kerato answered 4/8, 2018 at 6:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.