Reputation: 500
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
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
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
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
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
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
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
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