How to prevent items from getting duplicated when scrolling recycler view
Asked Answered
B

4

16

I have created a row inside recycler view and inside that I have inflated two rows or more but when I scroll the items are getting used again. I am not getting where to recycle view or remove them dynamically I need a feed and their comments.For comments I need to inflate layouts to display them below feeds for which getCommentInflaterView method is created.

But the view created using getCommentInflaterView() gets duplicated. MyAdapterClass:

public class AllFeedsAdapter extends
        RecyclerView.Adapter<AllFeedsAdapter.ViewHolder> {

    ArrayList<Data> arrayListAllFeedsData;
    Comment objComment;


    Context context;

    public AllFeedsAdapter(Context context, ArrayList<Data> data) {
        this.context = context;
        arrayListAllFeedsData = new ArrayList<>();
        arrayListAllFeedsData = data;
    }


    @Override
    public AllFeedsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        // Inflate the custom layout
        View post_row_view = inflater.inflate(R.layout.row_teacher_post, parent, false);

        // Return a new holder instance
        ViewHolder viewHolder = new ViewHolder(post_row_view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(AllFeedsAdapter.ViewHolder holder, int position) {

        holder.txtUsernamePostCreator.setText(arrayListAllFeedsData.get(position).getFull_name());
        holder.txtPostContent.setText(arrayListAllFeedsData.get(position).getFeed_text());
        holder.txtPostLikeCounter.setText(arrayListAllFeedsData.get(position).getTotal_like());
        holder.txtPostCommentsCounter.setText(arrayListAllFeedsData.get(position).getTotal_comment());

        if (arrayListAllFeedsData.get(position).getComment().size() > 0) {


            if (arrayListAllFeedsData.get(position).getComment().size() > 2) {
                for (int i = 0; i < 2; i++) {

                    objComment = arrayListAllFeedsData.get(position).getComment().get(i);

                    if (getCommentInflaterView(objComment) == null) {
                        holder.llCommentRowInflater.addView(getCommentInflaterView(objComment));
                    } else {
                        holder.llCommentRowInflater.removeAllViews();
                    }


                }
            } else {
                for (int i = 0; i < arrayListAllFeedsData.get(position).getComment().size(); i++) {

                    objComment = arrayListAllFeedsData.get(position).getComment().get(i);
                    if (getCommentInflaterView(objComment) == null) {
                        holder.llCommentRowInflater.addView(getCommentInflaterView(objComment));

                    } else {
                        holder.llCommentRowInflater.removeAllViews();
                    }

                }
            }

        }


    }

    private View getCommentInflaterView(Comment commentData) {

        LayoutInflater layoutInflater = LayoutInflater.from(context);
        View v = layoutInflater.inflate(R.layout.post_comments_list_item, null, false);

        TextView txtCommenterUsername = (TextView) v.findViewById(R.id.txt_username_commenter);
        TextView txtCommenterComment = (TextView) v.findViewById(R.id.txt_comments_from_commenter);
        TextView txtCommentDuration = (TextView) v.findViewById(R.id.txt_comment_duration);


        txtCommenterUsername.setText(commentData.getUsername());
        txtCommenterComment.setText(commentData.getComment());
        txtCommentDuration.setText(commentData.getCommentBy());


        return v;

    }

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

    /**
     * USed to create static class for all the view if listitem child
     */
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // Your holder should contain a member variable
        // for any view that will be set as you render a row

        public LinearLayout llParentTeacherPost, llCommentRowInflater;

        // We also create a constructor that accepts the entire item row
        // and does the view lookups to find each subview
        public ViewHolder(View itemView) {
            // Stores the itemView in a public final member variable that can be used
            // to access the context from any ViewHolder instance.
            super(itemView);
            llParentTeacherPost = (LinearLayout) itemView.findViewById(R.id.ll_parent_teacher_post);
            llCommentRowInflater = (LinearLayout) itemView.findViewById(R.id.ll_comment_row_inflater);

            imgDpPostCreator = (ImageView) itemView.findViewById(R.id.img_dp_post_creator);
            txtUsernamePostCreator = (TextView) 
        }


    }
}
Battologize answered 24/10, 2015 at 9:57 Comment(0)
O
100

Override these two methodes in adapter.

@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemViewType(int position) {
   return position;
}
Owades answered 23/8, 2016 at 7:52 Comment(12)
After nearly 1 hour of searching and trying. Thank you so MUCHCoworker
It works! But i don't know why. Could you please explain it?Charlatanism
Thank you so much. Never thought this could be the reason for the issue anyway eagerly waiting for the explanation.Butyraldehyde
@ChinglimCHAN It's related to the way android handles items without an id. Just hold ctrl (cmd on mac) pressed an click on the function name. You will do this twice and there is displayed: /** * Return the stable ID for the item at <code>position</code>. If { #hasStableIds()} * would return false this method should return {#NO_ID}. The default implementation * of this method returns {NO_ID}. * * position Adapter position to query * the stable ID of the item at position */Eucharist
We need more heroes like you!!Heroics
Like alex said, 1 hour searching and trying, thaaank youNiemann
@Prasad P This works good, but what if I need view types in my recyclerView?Callender
@Prasad P nice!Austen
2018 and it still Works...Praise God.. and thank you for the CORRECT ANSWER!Hoicks
@Callender This is not working for multiple View Types, any solution?Beersheba
This will mess up the design for "swipe to remove and collapse the list" systems if you have a recyclerview with such a functionality. It's no longer a smooth animation and instead becomes choppy / blinkyWashroom
It is not working for me, Am adding text views dynamically!Mayweed
D
3

inside your adapter class AllFeedsAdapter, you need to override the method:

@Override
public long getItemId(int position){
// return specific item's id here
}
Dextrorse answered 2/6, 2016 at 8:19 Comment(1)
Please be specific on what you want ? have a look at this on how to ask question stackoverflow.com/help/how-to-askDurwood
I
1

Worked for me Clear the content before loading the data in Recycler View

listOftrailers.clear();

Ipoh answered 10/7, 2018 at 18:32 Comment(0)
K
-3

At the end of onBindViewHolder method, include: holder.itemView.setTag(arrayListAllFeedsData.get(position));

Knavery answered 29/11, 2015 at 2:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.