60

简单来说:

我们如何定义 CardView 的 cardBackgroundColor 属性的颜色状态(在这种情况下,在 ListView 布局中)?

(我在安装了 4.4 的手机上使用 Android L 开发者预览版的 RC1,并在 build.gradle 中使用“com.android.support:cardview-v7:21.0.0-rc1”)

更长:

在 CardView 布局中,我们通过 cardCornerRadius 和 cardBackgroundColor 设置 CardView 的圆角半径和背景颜色。

但是,背景颜色不反映选定的状态,例如,如果列表项被按下。

但是,如果在 CardView 的内部视图中设置了背景颜色和相关的状态,它们会受到尊重,但是,它将显示在您在 CardView 中定义的角上。

那么,我们如何确保 CardView 的 cardBackgroundColor 中的状态得到尊重呢?

这是用于 cardBackgroundColor 的颜色 colour_with_states.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true"  android:state_enabled="false" android:state_pressed="true" android:color="@android:color/holo_green_dark" />
    <item android:state_focused="true"  android:state_enabled="false"                              android:color="@android:color/holo_green_dark" />
    <item android:state_focused="true"                                android:state_pressed="true" android:color="@android:color/holo_green_dark" />
    <item android:state_focused="false"                               android:state_pressed="true" android:color="@android:color/holo_green_dark" />
    <item android:state_focused="true"                                                             android:color="@android:color/holo_green_dark" />
    <!-- Only this below is seen in the cardview dispaly -->
    <item android:color="@android:color/holo_blue_bright" />
</selector>

以及使用 CardView 的布局:

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cardview="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    cardview:cardCornerRadius="10dp"
    cardview:cardBackgroundColor="@color/colour_with_states"
    >

<!-- If we set a background color below, it will overwrite our radius defined above -->
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:text="Lorem ipsum"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceListItem"
    android:background="@null"
    android:gravity="center_vertical"
    android:paddingTop="8dip"
    android:paddingBottom="8dip"
    android:paddingStart="8dip"
    android:paddingEnd="8dip"
    />

</android.support.v7.widget.CardView>
4

9 回答 9

67

虽然这并不理想,但由于边缘不是圆形的,您可以CardView像这样添加触摸反馈:

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardCornerRadius="4dp"
    android:clickable="true"
    android:foreground="?android:attr/selectableItemBackground">

    //Nested View ...

</android.support.v7.widget.CardView>

android:foregroundandroid:clickable属性添加到CardView.

这还有一个负面影响,因为该android:clickable属性会覆盖任何 clickListener,因此不会触发那些 clickListener。

更新

我有一些 CardView 实现的例子

循环(https://github.com/lawloretienne/Loop) - https://github.com/lawloretienne/Loop/blob/master/app/src/main/res/layout/category_card.xml

QuickReturn ( https://github.com/lawloretienne/QuickReturn ) - https://github.com/lawloretienne/QuickReturn/blob/master/sample/src/main/res/layout/activity_quick_return.xml

更新 2

经过更多研究,我为所有 API 版本(包括棒棒糖之前)的 CardViews 提出了一个很好的解决方案。

https://medium.com/@etiennelawlor/layout-tips-for-pre-and-post-lollipop-bcb2e4cdd6b2#.9h0v1gmaw

于 2014-09-15T21:00:43.987 回答
12

有时,您可能希望CardView获得视觉触摸反馈。该android:foreground="?android:attr/selectableItemBackground"解决方案非常适合这一点。

但是,您可以考虑drawSelectorOnTop(true)与您的 ListView 一起使用。这根本不需要对您进行任何更改CardView

让我知道是否需要进一步澄清。

于 2015-03-27T22:40:57.407 回答
6

这是我解决您问题的方法。

首先,创建一个名为CustomCardViewextends的自定义类CardView

然后重写该方法,当卡片按下状态发生变化时drawableStateChanged(),通过调用方法改变卡片背景颜色。setCardBackgroundColor()

最后,在你的布局文件中用这个 CustomCardView 替换 CardView。

此解决方案的唯一缺点是 cardview 无法在 Android 5.0 及更高版本上显示波纹按下效果。

这是我的代码:

public class CustomCardView extends CardView {

public CustomCardView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}

public CustomCardView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}

public CustomCardView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    // TODO Auto-generated constructor stub
}

@Override
protected void drawableStateChanged() {
    super.drawableStateChanged();
    if (isPressed()) {
        this.setCardBackgroundColor(getContext().getResources().getColor(R.color.card_view_pressed));
    } else {
        this.setCardBackgroundColor(getContext().getResources().getColor(R.color.card_view_normal));
    }
}

}

于 2015-06-10T12:59:11.977 回答
3

我使用的一种解决方法是通过在我的自定义 ViewHolder 中覆盖 View.OnTouchListener OnTouch() 事件处理程序以编程方式更改 UI。

@Override
public boolean onTouch (View v, MotionEvent event) 
{
    int action = event.getActionMasked();
    if (action == MotionEvent.ACTION_DOWN) 
    {
        mCardView.setCardBackgroundColor(STATE_PRESSED_COLOR);
    } 
    else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) 
    {
        mCardView.setCardBackgroundColor(DEFAULT_COLOR);
    }
    return false;
}
于 2015-03-04T22:12:44.683 回答
3

**只需在卡片视图中添加行**

    android:clickable="true"
    android:focusableInTouchMode="true"
    android:foreground="?android:attr/selectableItemBackground"
于 2016-03-02T09:49:06.963 回答
1

您可以在代码中使用颜色状态,它可以完美运行。

cardView.setCardBackgroundColor(context.getColorStateList(R.color.card_view_selectable))

在颜色 > card_view_selectable.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#4fc3f7" android:state_activated="true" />
    <item android:color="#fff" />
</selector>

然后使用 isActivated 导致背景颜色更改为 state_activated 或默认值。

cardView.isActivated = true    // or false
于 2019-11-25T12:58:12.120 回答
0

我使用了与卡片视图具有相同角半径的矩形形状。然后使用xml drawable作为cardview内部视图的背景。背景不显示在 cardview 角落,虽然我仍然在卡片和它的内部视图之间得到一个小填充。

在此处输入图像描述

于 2015-11-18T16:43:19.763 回答
0

如果您查看 carBackgroundColor 属性的定义,至少在android支持库中它是:

<resources>
    <declare-styleable name="CardView">
        <!-- Background color for CardView. -->
        <attr name="cardBackgroundColor" format="color" />
    </declare-styleable>
</resource>

这里它说它只需要cardBackgroundValue的颜色。我想这意味着选择器不被尊重,但会下降到默认值,即。选择器底部的颜色。

于 2017-01-30T14:26:51.987 回答
0

android:foregroundandroid:background<CardView/>. 下面是 CardView 的示例代码。

 <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:foreground="?android:attr/selectableItemBackground"
        app:cardCornerRadius="2dp"
        app:cardElevation="2dp">

// others view component 

</android.support.v7.widget.CardView>
于 2017-04-12T05:35:01.827 回答