Skip to content Skip to sidebar Skip to footer

Cardview's Background Which Will Respond To Android:state_selected And Android:state_pressed

I'm referring to the answer at https://stackoverflow.com/a/24475228/72437 The proposed answer is using drawable from Android : ?android:attr/selectableItemBackground This is what

Solution 1:

After experimenting for quite some time, I can pretty much conclude that this is limitation of current CardView - https://code.google.com/p/android/issues/detail?id=78198

Don't use CardView's foreground workaround. Although it is widely being proposed, it just don't work!

My suggestion is, avoid using CardView if you need a customized selector. Replace it LayerDrawable. Here's what I had done.

card.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item><shape><paddingandroid:top="1dp"android:right="1dp"android:bottom="1dp"android:left="1dp" /><solidandroid:color="@android:color/transparent" /><strokeandroid:width="1dp"android:color="#ffededed" /><cornersandroid:radius="2dp" /></shape></item><item><shape><paddingandroid:top="1dp"android:right="1dp"android:bottom="1dp"android:left="1dp" /><strokeandroid:width="1dp"android:color="#ffe8e8e8" /><cornersandroid:radius="2dp" /></shape></item><item><shape><paddingandroid:top="0dp"android:right="1dp"android:bottom="1dp"android:left="1dp" /><strokeandroid:width="1dp"android:color="#ffe1e1e1" /><cornersandroid:radius="2dp" /></shape></item><item><shape><paddingandroid:top="0dp"android:right="0dp"android:bottom="1dp"android:left="0dp" /><strokeandroid:width="1dp"android:color="#ffdbdbdb" /><cornersandroid:radius="2dp" /></shape></item><item><shape><paddingandroid:top="0dp"android:right="0dp"android:bottom="1dp"android:left="0dp" /><strokeandroid:width="1dp"android:color="#ffd5d5d5" /><cornersandroid:radius="2dp" /></shape></item>

    <!--
    <item><shape><paddingandroid:top="0dp"android:right="0dp"android:bottom="1dp"android:left="0dp" /><strokeandroid:width="1dp"android:color="#ffcfcfcf" /><cornersandroid:radius="2dp" /></shape></item>
    -->

    <item><shape ><solidandroid:color="#ffffffff" /><cornersandroid:radius="2dp" /></shape></item>
</layer-list>

card_selected.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item><shape><paddingandroid:top="1dp"android:right="1dp"android:bottom="1dp"android:left="1dp" /><strokeandroid:width="1dp"android:color="#ffededed" /><cornersandroid:radius="2dp" /></shape></item><item><shape><paddingandroid:top="1dp"android:right="1dp"android:bottom="1dp"android:left="1dp" /><strokeandroid:width="1dp"android:color="#ffe8e8e8" /><cornersandroid:radius="2dp" /></shape></item><item><shape><paddingandroid:top="0dp"android:right="1dp"android:bottom="1dp"android:left="1dp" /><strokeandroid:width="1dp"android:color="#ffe1e1e1" /><cornersandroid:radius="2dp" /></shape></item><item><shape><paddingandroid:top="0dp"android:right="0dp"android:bottom="1dp"android:left="0dp" /><strokeandroid:width="1dp"android:color="#ffdbdbdb" /><cornersandroid:radius="2dp" /></shape></item><item><shape><paddingandroid:top="0dp"android:right="0dp"android:bottom="1dp"android:left="0dp" /><strokeandroid:width="1dp"android:color="#ffd5d5d5" /><cornersandroid:radius="2dp" /></shape></item>

    <!--
    <item><shape><paddingandroid:top="0dp"android:right="0dp"android:bottom="1dp"android:left="0dp" /><strokeandroid:width="1dp"android:color="#ffcfcfcf" /><cornersandroid:radius="2dp" /></shape></item>
    -->

    <item><shape><solidandroid:color="#ffffe1b3" /><strokeandroid:width="1px"android:color="#fff76d3c" /><cornersandroid:radius="2dp" /></shape></item>
</layer-list>

statelist_item_background.xml

<?xml version="1.0" encoding="utf-8"?><selectorxmlns:android="http://schemas.android.com/apk/res/android"android:exitFadeDuration="@android:integer/config_mediumAnimTime"><itemandroid:state_pressed="true"android:drawable="@drawable/card_selected" /><!-- pressed --><itemandroid:state_selected="true"android:drawable="@drawable/card_selected" /><!-- pressed --><itemandroid:drawable="@drawable/card" /></selector>

layout.xml

<!-- A CardView that contains a TextView --><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:padding="10dp"android:layout_marginLeft="5dp"android:layout_marginRight="5dp"android:layout_marginTop="5dp"android:layout_marginBottom="5dp"android:background="@drawable/statelist_item_background"android:layout_width="match_parent"android:layout_height="match_parent"android:clickable="true" ><TextViewandroid:id="@+id/txt_label_item"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceLarge"tools:text="Item Number One" /><TextViewandroid:id="@+id/txt_date_time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"tools:text="Item Number One" /></LinearLayout>

You will get the pretty nice outcome.

enter image description here

Solution 2:

I've just tried MaterialCardView and this works:

<com.google.android.material.card.MaterialCardView
    android:id="@+id/material_card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/activity_vertical_margin"
    app:cardCornerRadius="4dp"
    app:cardBackgroundColor="@color/selector_background_color"
    app:strokeWidth="2dp">

selector_background_color.xml

<?xml version="1.0" encoding="utf-8"?><selectorxmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:color="@android:color/white"android:state_activated="true"/><itemandroid:color="@android:color/darker_gray"android:state_activated="false"/>

In the Activity/Fragment:

material_card_view.setOnClickListener {
        it.isActivated = !it.isActivated
}

For the strokeColor though, you can't use a selector. You will have to do it programmatically if you want the stroke color to change as per selector state.

Example for state_activated:

val colorStateList: ColorStateList = 
ResourcesCompat.getColorStateList(resources, 
R.color.selector_stroke_color, null)!!
val colorForState =colorStateList.getColorForState(intArrayOf(android.R.attr.state_activated), colorStateList.defaultColor)
material_card_view.strokeColor = colorForState

Solution 3:

All my card content (TextViews) are blocked. How can I avoid such?

Your blocked issue can easily be solved with some color theory knowledge. Instead of using the given peach color, you could use a variant of the peach shade with a higher transparency.

Color Code scheme in Android xxyyyyyy

xx is your transparency level, and y's are your color.

xx max value is : ff // this is fully visible

xx min value is : 00 // this is full invisible

So by playing around on the color wheel, you can get the right effect with the right amount of transparency needed for your view.

Solution 4:

for the background not covering the entire card issue, it is due to the cornerRadius drawing limitation. There are two solutions for this:

  1. Disable round corner for your card will resolve the problem. app:cardCornerRadius="0dp"

  2. You can retain cardCornerRadius but you need to set app:cardPreventCornerOverlap="false"

Solution 5:

MaterialCardView has ripple effect and doesn't need a custom background drawable as opposed to CardView. That handled the android:state_selected and android:state_pressed for my use case.

Post a Comment for "Cardview's Background Which Will Respond To Android:state_selected And Android:state_pressed"