SARATH V
SARATH V

Reputation: 500

Recycler view item colour change repeating after scrolling

Recycler view item color change repeating after scrolling.

I used to change color at a particular position of the Recyclerview list. When scrolling occurs another item at the bottom has the same change. And it is repeating in pattern. How to resolve this?

 holder.recycle_Listing.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            itemListener.connectionClicked(v,position, itemtype);

            holder.mainlayout.setBackgroundColor(Color.parseColor("#e927a4d1"));

        }
    });

Upvotes: 4

Views: 4094

Answers (7)

Young Lee
Young Lee

Reputation: 21

Recyclerview & Room Database in Kotlin.

in Activity: //to send position to Adapter

val putPosition = 5   // what you want to be position
Handler(Looper.getMainLooper()).postDelayed({
       (Recyclerview.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(putPosition-1,0)
}, 1500)
//
//
// out of onCreate (for companion)
fun getVersePosition() = putPosition

in Adapter: // to get position from Activity

override fun onBindViewHolder(holder: Adapter.Holder, position: Int) {
    val roomData = listData[position]
    holder.setRoomData(roomData)
    val activity : MainActivity.Companion = MainActivity
    val getPosition : Int? = activity.companionMainActivity?.getVersePosition()
    if (position == getPosition-1){
            holder.itemView.setBackgroundColor(Color.parseColor("#AFB42B"))
        } else {
            holder.itemView.setBackgroundColor(Color.TRANSPARENT)
        }
}

SparseBooleanArray() doesn't need and bind doesn't need too.

But it's very important

holder.itemView.setBackgroundColor(Color.TRANSPARENT)

If omitted, repetition will occur.

Upvotes: 0

SARATH V
SARATH V

Reputation: 500

Just saved every item keys in an array and that selected array also passed through my Adapter class. Even simple colour change works fine in this format. Here the code is changed as per my the requirement.

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

        JsonObject object = dataArray.get(position).getAsJsonObject();
        if(selectedArray.contains(object.get("userkey").getAsString()))
        {
            GradientDrawable borCol = new GradientDrawable();
            borCol.setCornerRadius(7);
            borCol.setColor(Color.parseColor("#ffffff"));
            borCol.setStroke(2, Color.parseColor("#60B9E1"));
            holder.recycle_Listing.setBackgroundDrawable(borCol);
           //holder.mainlayout.setBackgroundColor(Color.parseColor("#e927a4d1"));
        }
        else
        {
            GradientDrawable borCol = new GradientDrawable();
            borCol.setCornerRadius(7);
            borCol.setColor(Color.parseColor("#ffffff"));
            borCol.setStroke(1, Color.parseColor("#e0e0e0"));
            holder.recycle_Listing.setBackgroundDrawable(borCol);
          //holder.mainlayout.setBackgroundColor(Color.parseColor("#f1f1f1"));
        }


            holder.profileName.setText(object.get("name").getAsString());

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


                holder.mainlayout.setSelected(!holder.mainlayout.isSelected());

                if (holder.mainlayout.isSelected()) {
                    GradientDrawable borCol = new GradientDrawable();
                    borCol.setCornerRadius(7);
                    borCol.setColor(Color.parseColor("#ffffff"));
                    borCol.setStroke(2, Color.parseColor("#60B9E1"));
                    holder.recycle_Listing.setBackgroundDrawable(borCol);
                  //  holder.mainlayout.setBackgroundColor(Color.parseColor("#11B5DA"));
                } else {
                    GradientDrawable borCol = new GradientDrawable();
                    borCol.setCornerRadius(7);
                    borCol.setColor(Color.parseColor("#ffffff"));
                    borCol.setStroke(1, Color.parseColor("#e0e0e0"));
                    holder.recycle_Listing.setBackgroundDrawable(borCol);
                   // holder.mainlayout.setBackgroundColor(Color.parseColor("#f1f1f1"));
                }



                itemListener.connectionClicked(v,position, itemtype);


               //holder.mainlayout.setBackgroundColor(Color.parseColor("#11B5DA"));
              //holder.mainlayout.setBackgroundColor(Color.parseColor("#f1f1f1"));
            }
        });



    }

This code works fine with no repeated colour change in recycler. If any queries feel free to ask via comments or chat

Upvotes: 0

Sharath kumar
Sharath kumar

Reputation: 4132

The recycler view recycles the view in OnBindViewHolder.So when items are clicked it gets reflected in some other positions.To solve this. create a global SparseBooleanArray to store the clicked position.

private final SparseBooleanArray array=new SparseBooleanArray();

Then inside final viewholder add the clickListener and onClick store the position of the clicked item.

public class ViewHolder extends RecyclerView.ViewHolder {
    public YOURVIEW view;
    public ViewHolder(View v) {
        super(v);
        view = (YOURVIEW) v.findViewById(R.id.YOURVIEWID);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                array.put(getAdapterPosition(),true);
                notifyDataSetChanged();
            }
        });
    }
}

And in inside OnBindViewHolder,

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    if(array.get(position)){
        holder.mainlayout.setBackgroundColor(Color.parseColor("#e927a4d1"));
    }else{
        holder.mainlayout.setBackgroundColor(UNSELECTEDCOLOR);
    }
}

Upvotes: 5

CoXier
CoXier

Reputation: 2663

I think you can set your background color in void onBindViewHolder(VH holder, int position); such as

List<Integer> selectedPosition = new ArrayList(yourDataSize);
void onBindViewHolder(VH holder, int position){

     if(selectedPosition.get(position) == 1){
       holder.mainlayout.setBackgroundColor(Color.parseColor("#e927a4d1"));
     }else {
       holder.mainlayout.setBackgroundColor(normalColor);
     }

     //when the item clicked 
     selectedPosition.add(position,1);

}

Upvotes: 1

Munir
Munir

Reputation: 2558

try to implement this method in your adapter class, may be it's solve your problem

@Override
    public void onViewRecycled(ViewHolderProduct holder) {
        super.onViewRecycled(holder);
        holder.mainlayout.removeAllViews();
} 

Upvotes: 0

user3856376
user3856376

Reputation: 75

It is due to recycling of viewholder of recycler view. Try this It worked for me.

public ListViewHolder(View itemView) {
        super(itemView);

        this.setIsRecyclable(false);


    }

Upvotes: 0

Ankur Mishra
Ankur Mishra

Reputation: 103

That function returns relative position not absolute so when screen is scrolled position is replaced with a new value. use position from your list for the desired result.

Upvotes: 0

Related Questions