Why is this not setting Recycler View item background color?

Viewed 42

I am trying to set a recyclerview item color based on a boolean in kotlin. But when the recylerview loads, it will not set its color with the code I have. Also, If I change the background that is tied to the recycler view item via xml programmatically, it will not change it to the new drawable, but will reset it back to its basic form. Please just at least let me know why my setBackgroundColor line is not setting the list item background to the color I designate.

@RequiresApi(Build.VERSION_CODES.O)
override fun onBindViewHolder(holder: AlarmViewHolder, position: Int) {

    val alarm = alarmList[position]



    holder.itemView.apply {

if (alarm.amPm) {

setBackgroundColor(context.getColor(R.color.todays_day_color))
}

Thanks all for the responses, I know it takes time to respond. Ty. I have marked the answer that solved it for me. I had to refer to the parent/child/whichever it is view layout and change its color and not the items color.

if (alarm.amPm) { list_item_layout_id.setBackgroundColor(context.getColor(R.color.todays_day_color)) } else list_item_layout_id.setBackgroundColor(context.getColor(R.color.black))

4 Answers

I faced the same issue once Try to set the ackground color for your child's item

set background color for android:id="@+id/itemBackground"

layout_item.xml

e.g

 <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:id="@+id/itemBackground"
        android:padding="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView" />
    </LinearLayout>
</FrameLayout>

Try writing the else loop also

I also once faced the same problem writing the else loop solved it for me.

if (alarm.amPm) {
setBackgroundColor(context.getColor(R.color.todays_day_color))
} else {
setBackgroundColor("YOUR COLOR")
}

To set the background color without struggling with radius, use MaterialCardView, you can set the corner radius, give stroke and set background color as well. In your layout use MaterialCardView as parent view.

 <com.google.android.material.card.MaterialCardView
   android:id="@+id/mcv"
   app:cardBackgroundColor="@color/black_4a"
   app:strokeColor="@color/cyan_500"
   app:strokeWidth="1dp"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_marginTop="@dimen/_5sdp"
   android:elevation="14dp"
   app:cardCornerRadius="5dp">
 </com.google.android.material.card.MaterialCardView>

After this you can set the background color from adapter like

holder.mcv.setBackgroundColor(context.getColor(R.color.todays_day_color))

In onBindViewHolder, for any part of the ViewHolder that can change, you have to explicitly update it so it's correct for the current item. If you don't, because the ViewHolders get recycled you can end up with parts of the VH displaying things that were set by a different item that used the VH earlier.

So this:

if (alarm.amPm) {
    setBackgroundColor(context.getColor(R.color.todays_day_color))
}

has to have an else that sets the colour it should display if amPm isn't true, like Siddarth Jain says. You need to set that state either way - you don't want to only update it if amPm is true, but leave it showing whatever it was already displaying otherwise.


As for your background drawable, if you set a background colour, that's a drawable in itself - just a plain, flat colour drawable that fills the View's rectangle. So it'll replace any background drawable you had before. If you want the original drawable back, you'll have to call setBackground with that drawable (e.g. using ContextCompat.getDrawable to create a Drawable instance from a drawable resource ID).

What you might want instead, is to tint the background. That lets you have whatever background drawable you like, and also apply a colour to it, so they're two separate things. That way, all you need to change is the tint.

You can do that with something like

backgroundTintList = ContextCompat.getColorStateList(context, R.color.todays_day_color)
// you might also want to set another tint mode, depending on how you want it to look, e.g.
backgroundTintMode = PorterDuff.Mode.OVERLAY

The default SRC_IN mode will apply the tint as a flat colour over the shape of your background drawable, instead of just filling the view with a rectangle. The different blending modes (like OVERLAY or MULTIPLY) will allow detail on the background drawable to show through - you'll have to try them out to see which one gives you what you want

Related