当使用 CardView 的场合是作为列表中的一个 Item 且直接单击 Item 有相应的操作,那么就有必要加上视觉反馈来告诉用户这个 Card 是可点击的。

直接给 CardView 加上 android:foreground="?attr/selectableItemBackground" 这个属性会在 Lollipop 上自动加上 Ripple 效果,在旧版本则是一个变深/变亮的效果。​

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:layout_margin="3dp"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
>

注意:此布局文件必须在res\layout-v21下。



如果你没使用这个支持库或者觉得这个效果在旧版本显得有点僵硬:
你可以尝试自定义一个 Drawable,和上一条一样根据不同 SDK 版本分别编写不同的效果,在此就不多介绍自定义 Drawable 的方法。

其他注意问题:

注意不同 SDK 版本(低于 Lollipop 21)上的边距(Margin)效果

Google 在 Android Lollipop 中引入了 Material Design 设计中的阴影(Elevation)和 Z 轴位移,其目的就是突出界面中不同元素之间的层次关系。为了统一不同系统版本的视觉效果,Google 针对 SDK 21 以下的系统给 CardView 加入一个 Elevation 兼容(即 XML 中的 app:cardElevation 和 Java 代码中的 setCardElevation)。
然而,在低版本中设置了 CardElevation 之后 CardView 会自动留出空间供阴影显示,而 Lollipop 之后则需要手动设置 Margin 边距来预留空间,导致我在设置 Margin 在 Android 5.x 机器上调试好后,在 Kitkat 机器调试时发现边距非常大,严重地浪费了屏幕控件。
因此,我们需要自定义一个 dimen 作为 CardView 的 Margin 值:

  1. 创建 /res/value 和 /res/value-v21 资源文件夹于项目对应 Module 目录下,前者放置旧版本/通用的资源文件(了解的可以跳过),后者放置 21 及更高 SDK 版本的资源文件。
  2. 在 value 内的 dimen.xml 创建一个 Dimension (<dimen> 属性),随便命个名(如 xxx_card_margin)并填入数值 0dp。
  3. 接着在 value-v21 文件夹内的 dimen.xml 创建名字相同的 Dimension,并填入你期望的预留边距(一般和 CardElevation 阴影大小相同)
  4. 最后,在你布局中的 CardView 中设置

​android:layout_margin="@dimen/xxx_card_margin"​

这样依赖就解决了低版本中边距过大或者视觉效果不统一的问题了。


◆ 尽量不要用作固定高度的 List Item

除了横向滚动列表和类似 Google Play 音乐中的带封面图片卡片 Item,其他地方应该尽量避免做固定高度的卡片。
举一个错误例子,我之前写的快递查询应用「水表助手」,快递卡片就是用了固定宽度(误人子弟系列QAQ)

Android CardView 设置点击效果_xml

不需要用卡片的地方也不应该使用,滥用只会让用户更快地厌倦你的界面设计。

Android CardView 设置点击效果_边距_02

(这个是复制自官方的错误范例)

 

◆ 低版本(低于 Lollipop)的 setElevation 不是万能的

由于缺少一些系统 API(如 RenderThread),CardView 中的 Elevation 兼容实现并不完美,和真正的实现方法还是有较大的差距(不是指效果),所以调用 setCardElevation 也不能随心所欲地传入一个 Float 型,在低版本系统使用时应当处理一下传入的数值或加上 try-catch (不推荐)。