CardView背景颜色状态不被尊重

简单来说:

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

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

更长:

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

但是,背景颜色不会影响选定的状态,例如,如果按下列表项目。

如果在CardView的内部视图中设置了背景颜色和相关的状态,但是它将显示在CardView中定义的angular上。

那么,我们如何确保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> 

虽然这并不理想,但由于边缘不是圆形的,因此可以将触摸反馈添加到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> 

CardView添加android:foregroundandroid:clickable属性。

此外,这有一个消极的副作用,因为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

经过更多的研究,我已经为包括pre-Lollipop在内的所有API版本的CardViews提供了一个很好的解决scheme。

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

有时,您可能希望CardView具有视觉触摸反馈。 android:foreground="?android:attr/selectableItemBackground"解决scheme是完美的。

不过,你可以考虑在你的ListView中使用drawSelectorOnTop(true) 。 根本不需要更改CardView

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

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

首先创build一个名为CustomCardView的自定义类扩展CardView

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

最后,在您的布局文件中用此CustomCardViewreplaceCardView。

这个解决scheme唯一的缺点是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)); } } 

}

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

**只需在卡片视图内添加行即可**

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

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

在这里输入图像说明

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

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

这里说它只需要cardBackgroundValue的颜色。 我想这意味着select不被尊重,但落在默认值即。 select器底部的颜色。

<CardView/>使用android:foreground而不是android:background 。 以下是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>