Search code examples
androidbackground-colorstrokematerialcardview

MaterialCardView change background color and stroke color programmatically


Pro devs. I'll try to change the card view background and stroke color programmatically but all times card.setCardBackgroundColor() override the stroke color. Statically in XML, it works well. But programmatically it make an effect like this.

val colorWithAlpha = ColorUtils.setAlphaComponent(tagColor, 128)
tagView.card.setStrokeColor(ColorStateList.valueOf(colorWithAlpha))
tagView.card.setCardBackgroundColor(ColorStateList.valueOf(tagColor))

Same for: card.backgroundTintList = ColorStateList.valueOf(tagColor)

XML:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/card"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:cardBackgroundColor="#DB8A61"
    app:cardCornerRadius="8dp"
    app:cardElevation="0dp"
    app:cardUseCompatPadding="true"
    app:cardPreventCornerOverlap="true"
    app:strokeColor="#EBD3C7"
    app:strokeWidth="4dp">

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/tag_text"
        style="@style/SmallLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:lines="1"
        android:paddingStart="8dp"
        android:paddingTop="4dp"
        android:paddingEnd="8dp"
        android:paddingBottom="4dp"
        android:textColor="@color/white"
        app:autoSizeMaxTextSize="100sp"
        app:autoSizeMinTextSize="5sp"
        app:autoSizeStepGranularity="1sp"
        app:autoSizeTextType="uniform"
        tools:text="Some Text" />

</com.google.android.material.card.MaterialCardView>

How it looks: XML: enter image description here

Doing that in code:

private fun createAddTagView(tagName: String, tagColor: Int, container: ViewGroup) {
        val tagView = LayoutTagBinding.inflate(inflater, container, true)
        tagView.tagText.text = tagName
        val colorWithAlpha = ColorUtils.setAlphaComponent(tagColor, 128)
        tagView.card.setStrokeColor(ColorStateList.valueOf(colorWithAlpha))
        tagView.card.setCardBackgroundColor(ColorStateList.valueOf(tagColor))
    }

enter image description here

When Removing: tagView.card.setCardBackgroundColor(ColorStateList.valueOf(tagColor))

enter image description here

When there are no Programmatic changes (colors setup by XML) Looks like expected:

enter image description here

How to make it like in XML show?


Solution

  • I believe that the problem is not in the MaterialCardView background/stroke methods; but that the used color shades in the layout are different than those used programmatically.

    The used colors in layout:

    app:cardBackgroundColor="#DB8A61"
    app:strokeColor="#EBD3C7"
    

    But programmatically, you use tagColor and add alpha channel to it with colorWithAlpha; you didn't provide the tagColor; but adding 128 alpha component would not change that much; and that is totally different than the layout colors that don't have alpha component at all.

    So, to have the same colors programmatically, just reuse the same layout colors without alpha component:

    tagView.card.setCardBackgroundColor(ColorStateList.valueOf(Color.parseColor("#DB8A61")))
    tagView.card.setStrokeColor(ColorStateList.valueOf(Color.parseColor("#EBD3C7")))