6

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);
    }
}

}

Ashwani Kumar
  • 1,251
  • 1
  • 16
  • 25

7 Answers7

25

You need to use this 3 lines to make it work

mItemList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mItemList.size());
Jay
  • 457
  • 8
  • 15
  • 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. :( – Jay Sep 25 '18 at 14:16
  • have you tried overriding this two methods? Override public int getItemViewType(int position) { return position; } Override public long getItemId(int position) { return position; } – Jay Sep 26 '18 at 10:36
  • 1
    @Jay 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. – Aris Panayiotou Oct 24 '18 at 08:15
  • @jaydeeppipaliya Is there any similar code available for notifyItemMoved(fromPosition, to Position) ? – Sethuraman Srinivasan Jan 02 '19 at 06:51
  • 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. – Kartik May 20 '19 at 13:35
1
private void removerecyclerItem(DraftStoriesPojo list) {
        int current_position = allStoriesPojoList.indexOf(list);
        allStoriesPojoList.remove(current_position);
        notifyItemRemoved(current_position);
        notifyItemRangeChanged (current_position, getItemCount());
    }
Kishore Reddy
  • 2,002
  • 16
  • 14
1

Declare a method in your custom RecylerView like below

public void DeleteData(int position){

        recordingItems.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, recordingItems.size());
    }

and from mainActivity call

adapter.DeleteData(position);
taras
  • 5,216
  • 9
  • 32
  • 41
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();
    }
}
Ashok Kateshiya
  • 429
  • 2
  • 10
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);
        }
    }
});
Saurabh Padwekar
  • 2,982
  • 1
  • 24
  • 29
  • 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. – Ashwani Kumar Jul 31 '17 at 10:40
  • no need to do mItemList.clear(),mItemList.addAll(mOriginalItemList) these things – Saurabh Padwekar Jul 31 '17 at 10:44
  • 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. – Ashwani Kumar Jul 31 '17 at 10:53
  • 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 :/. – Saurabh Padwekar Jul 31 '17 at 10:55
  • 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. – Ashwani Kumar Jul 31 '17 at 11:02
  • oh now i got it, previously removed item should be there oh ok – Saurabh Padwekar Jul 31 '17 at 11:05
0

Only add these two lines

mItemList.remove(position);
notifyDataSetChanged();
Navjot.jassal
  • 667
  • 9
  • 26
-1

You need to use these lines to make it work

mItemList.remove(position);
notifyDataSetChanged();
Buddy
  • 10,120
  • 5
  • 37
  • 57
neha
  • 1
  • 8