Reputation: 21
I'm trying to change the color of a CardView
depending if is selected or not
I tried this, this is my card_view_color.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:color="#ABEBC6"/> <!-- selected -->
<item android:state_selected="false"
android:color="#FFFFFF"/> <!-- not selected -->
</selector>
This is my CardView
:
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardBackgroundColor="@color/card_view_color"
android:id="@+id/cardViewMetric">
</androidx.cardview.widget.CardView>
Also tried with android:state_activated
, android:state_checked
and is the same result, not working.
I also have a onClickListener
(Kotlin):
holder.binding.root.setOnClickListener{
val GREEN_COLOR = Color.parseColor("#ABEBC6")
holder.binding.cardViewMetric.setCardBackgroundColor(GREEN_COLOR)
}
That has this current behavior.
The wanted behavior I want is only one CardView is gonna be colored, and if I select another one that one is gonna be green and the previous selection is gonna be white.
Upvotes: 2
Views: 4673
Reputation: 1283
Here's the kotlin way :
create an extension function like that:
fun MaterialCardView.managePressed(onClick: () -> Unit) {
this.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
this.setCardBackgroundColor(context.mutedColor(R.color.onpressed_color))
}
MotionEvent.ACTION_UP -> {
this.setCardBackgroundColor(context.mutedColor(R.color.on_clicked_done_color))
onClick.invoke()
}
MotionEvent.ACTION_CANCEL -> {
this.setCardBackgroundColor(context.mutedColor(R.color.default_color))
}
else -> {
}
}
false
}
Usage:
yourCardView.managePressed() {
//click_listner_call_back_will_be_here
}
Upvotes: 0
Reputation: 21
Thanks to the answer of Gabriele Mariotti it gave me an idea:
I changed my CardView to:
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardBackgroundColor="@color/card_view_color"
android:focusableInTouchMode="true"
android:id="@+id/cardViewMetric">
</androidx.cardview.widget.CardView>
(added the focusableInTouchMode attribute)
And in my card_view_color.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:color="#ABEBC6"/> <!-- selected -->
<item android:state_focused="false"
android:color="#FFFFFF"/> <!-- not selected -->
</selector>
And now it has the wanted behavior
EDIT: forgot to say that setOnClickListener is not needed
Hope it helps to anyone=)
Upvotes: 0
Reputation: 364868
You can use the MaterialCardView
in the Material Components Library.
<com.google.android.material.card.MaterialCardView
...
app:checkedIcon="@null"
android:clickable="true"
android:focusable="true"
android:checkable="true">
</com.google.android.material.card.MaterialCardView>
Then in your code:
card.setChecked(true)
The MaterialCardView
extends the androidx.cardview.widget.CardView
and support the checking
state.
To customize the color you can use the app:cardForegroundColor
attribute:
<com.google.android.material.card.MaterialCardView
app:cardForegroundColor="@color/card_selector"
with:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:alpha="...." android:color="@color/..." android:state_checked="true"/>
<item android:alpha="...." android:color="@color/..." app:state_dragged="true"/>
<item android:color="@android:color/transparent" android:state_checked="false" app:state_dragged="false"/>
</selector>
or you can override the colorPrimary
in the card:
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
style="@style/Widget.MaterialComponents.CardView"
with:
<style name="ThemeOverlay.CardView" parent="">
<item name="colorPrimary">@color/....</item>
</style>
By default the checked card has also a checked icon on the top right corner. You can customize it using the app:checkedIcon
attribute or you can hide it using app:checkedIcon="@null"
.
Upvotes: 1