CardView背景颜色状态未受到尊重

时间:2014-08-17 19:36:58

标签: android android-cardview

简而言之:

我们如何定义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>

9 个答案:

答案 0 :(得分:60)

虽然这不理想,但由于边缘没有圆角,您可以像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

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

更新2

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

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

答案 1 :(得分:10)

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

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

如果需要进一步澄清,请告诉我。

答案 2 :(得分:5)

这是我解决问题的方法。

首先,创建一个名为CustomCardView extends 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));
    }
}

}

答案 3 :(得分:2)

我使用的一种解决方法是通过覆盖自定义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;
}

答案 4 :(得分:2)

**只需在卡片视图中添加线条**

    android:clickable="true"
    android:focusableInTouchMode="true"
    android:foreground="?android:attr/selectableItemBackground"

答案 5 :(得分:0)

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

enter image description here

答案 6 :(得分:0)

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

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

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

答案 7 :(得分:0)

android:foreground中使用android: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>

答案 8 :(得分:0)

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

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