CardView 简介和使用
CardView 是 Google 官方发布 MD 风格卡片布局控件,开发者可以很方便的使用它将布局做成卡片效果。在使用 CardView 之前,多少应该对它有一定的了解,下面将对其实现做简单的介绍。
CardView 继承自 FrameLayout,并在其基础上添加了圆角和阴影等效果。为了更方便的使用这些效果,Google 提供了一系列的自定义属性,这些属性在类注释中都有列出来,如下:
* @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor
* @attr ref android.support.v7.cardview.R.styleable#CardView_cardCornerRadius
* @attr ref android.support.v7.cardview.R.styleable#CardView_cardElevation
* @attr ref android.support.v7.cardview.R.styleable#CardView_cardMaxElevation
* @attr ref android.support.v7.cardview.R.styleable#CardView_cardUseCompatPadding
* @attr ref android.support.v7.cardview.R.styleable#CardView_cardPreventCornerOverlap
* @attr ref android.support.v7.cardview.R.styleable#CardView_contentPadding
* @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingLeft
* @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingTop
* @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingRight
* @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingBottom
*/
public class CardView extends FrameLayout {
这些属性的作用和用法如下:
CardView_cardCornerRadius 设置圆角大小
CardView_cardElevation 设置z轴阴影
CardView_cardMaxElevation 设置z轴最大高度值
CardView_cardUseCompatPadding 是否使用CompadPadding
设置内边距,V21+的版本和之前的版本具有一样的计算方式。
部分机器不开这个属性会导致卡片效果“消失”,如荣耀6(6.0系统)。
在V20和之前的版本中添加内边距,这个属性为了防止内容和边角的重叠
CardView_contentPaddingLeft 内部左侧边距
CardView_contentPaddingTop 内部顶部边距
CardView_contentPaddingRight 内部右侧边距
CardView_contentPaddingBottom 内部底部边距
CardViewImpl 接口
跟着源码往下看,接下来就是做多 API 版本适配的代码,这段代码使得不同版本的 Android 能达到相同或者相似的效果,尽可能的做到了兼容。这里 CardViewImpl 的几个子类实现请自行查阅,这里不多说了。
if (Build.VERSION.SDK_INT >= 21) {
IMPL = new CardViewApi21Impl();
} else if (Build.VERSION.SDK_INT >= 17) {
IMPL = new CardViewApi17Impl();
} else {
IMPL = new CardViewBaseImpl();
}
IMPL.initStatic();
}
上面这段代码很有意思,首先它是static{}包裹的静态代码块,而静态代码块是属于类的,只会在类被加载到内存时执行一次,以后不管如何实例化,new 出多少实例对象,静态代码块都不会再执行了。其次,IMPL 对象是是static final修饰的,这就意味着 IMPL 对象也是属于类,并且只能被初始化一次。
基本类型+String的值、复杂类型的引用,存储在栈中;复杂类型的实体类容存储在堆中。final 是指明栈中的类容不能修改。
* Interface for platform specific CardView implementations.
*/
interface CardViewImpl {
void initialize(CardViewDelegate cardView, Context context, ColorStateList backgroundColor,
float radius, float elevation, float maxElevation);
void setRadius(CardViewDelegate cardView, float radius);
float getRadius(CardViewDelegate cardView);
void setElevation(CardViewDelegate cardView, float elevation);
float getElevation(CardViewDelegate cardView);
void initStatic();
void setMaxElevation(CardViewDelegate cardView, float maxElevation);
float getMaxElevation(CardViewDelegate cardView);
float getMinWidth(CardViewDelegate cardView);
float getMinHeight(CardViewDelegate cardView);
void updatePadding(CardViewDelegate cardView);
void onCompatPaddingChanged(CardViewDelegate cardView);
void onPreventCornerOverlapChanged(CardViewDelegate cardView);
void setBackgroundColor(CardViewDelegate cardView, @Nullable ColorStateList color);
ColorStateList getBackgroundColor(CardViewDelegate cardView);
}
不难发现,这里面几乎所有方法都有一个参数——CardViewDelegate,在CardView的方法调用时,会通过早已初始化的 IMPL 调用对应的方法,并传入一个mCardViewDelegate对象,并通过它进行下一步操作。如:
* Updates the background color of the CardView
*
* @param color The new color to set for the card background
* @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor
*/
public void setCardBackgroundColor(@ColorInt int color) {
IMPL.setBackgroundColor(mCardViewDelegate, ColorStateList.valueOf(color));
}
CardViewDelegate 代理
接下来就简单说下 CardViewDelegate 对象是如何工作的。
首先是定义,这一系列方法定义与 CardView 提供的方法迷之相似。
* Interface provided by CardView to implementations.
* <p>
* Necessary to resolve circular dependency between base CardView and platform implementations.
*/
interface CardViewDelegate {
void setCardBackground(Drawable drawable);
Drawable getCardBackground();
boolean getUseCompatPadding();
boolean getPreventCornerOverlap();
void setShadowPadding(int left, int top, int right, int bottom);
void setMinWidthHeightInternal(int width, int height);
View getCardView();
}
然后 CardViewDelegate 的实例化是在 CardView 中进行的,在 CardView 代码末尾可看到其实现:
······
}
这里没有使用 static,那么这个 mCardViewDelegate 对象在 CardView 实例化时也会 new 一个新的,然后通过不同 mCardViewDelegate 对象,就做到了一个系统上不同CardView有不同表现。

添加依赖库
CardView 是随 MD 推出的补充库,并非 SDK 的内容,因此在使用 CardView 时,必须先引入依赖库:
1
使用 CardView 布局
前面已经介绍了,CardView 继承自 FrameLayout,那么我们就可以直接在布局中,将CardView作为容器,放入其它控件即可。
如果已有现成的布局,想再引入卡片效果,也只需要在已有布局最外层添加 CardView 即可。
举个栗子:
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp8"
android:orientation="vertical"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="@dimen/dp8"
app:cardElevation="@dimen/dp8"
app:cardUseCompatPadding="true"
app:contentPadding="@dimen/dp8">
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试\n卡片\n效果"
android:textSize="@dimen/sp32" />
前面介绍属性已经说了,部分机器(如荣耀6,6.0系统)如果不打开 cardUseCompatPadding,将不会呈现出卡片效果。因此建议打开。

要实现卡片效果,除了用 CardView 以外,还有其它方法,比如使用shape+elevation。
举个栗子:
先定义一个shape,用作背景。
android:shape="rectangle">//shape样式
//圆角
<corners android:radius="@dimen/dp8" />
//边框
<stroke
android:width="1dp"
android:color="@color/divider" />
//内边距
<padding
android:bottom="@dimen/dp8"
android:left="@dimen/dp8"
android:right="@dimen/dp8"
android:top="@dimen/dp8" />
//内部填充
<solid android:color="@color/white" />
</shape>
然后在布局中引用:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:layout_margin="@dimen/dp8"
android:background="@drawable/shape"
android:elevation="@dimen/dp8" //z轴高度,控制阴影效果
android:text="测试\n卡片\n效果"
android:textSize="@dimen/sp32" />
运行效果:

但是,elevation属性也是随MD出来的,它只支持 5.0+(也就是API21+)的系统。因此,如果要卡片效果能想兼容低版本系统,那还是应该优先考虑用 CardView。
————————————————
CardView 简介和使用的更多相关文章
- Android零基础入门第71节:CardView简单实现卡片式布局
还记得我们一共学过了多少UI控件了吗?都掌握的怎么样啊. 安卓中一些常用控件学习得差不多了,今天再来学习一个新的控件CardView,在实际开发中也有非常高的地位. 一.CardView简介 Card ...
- 【转】GitHub 排名前 100 的安卓、iOS项目简介
GitHub Android Libraries Top 100 简介 排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果, 然后过滤了跟 Android 不 ...
- GitHub Android Libraries Top 100 简介
本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍, 至于排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果, 然后过 ...
- RecyclerView,CardView导入和使用(Demo)
简介: 这篇文章是ANDROID L——Material Design详解(UI控件)的一个补充或者说是应用实例,如果有时间建议大家稍微浏览一下上篇文章. 本文主要介绍Android L新增加的两个U ...
- 2016年GitHub 排名前 100 的安卓、iOS项目简介(收藏)
排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果, 然后过滤了跟 Android 不相关的项目, 所以排名并不具备任何官方效力, 仅供参考学习, 方便初学者 ...
- 64.GitHub 排名前100的android项目简介
GitHub Android Libraries Top 100 简介 排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果, 然后过滤了跟 Android 不 ...
- Android5.0新特性——Material Design简介
Material Design Material Design简介 Material Design是谷歌新的设计语言,谷歌希望寄由此来统一各种平台上的用户体验,Material Design的特点是干 ...
- GitHub Android Librarys Top 100 简介
GitHub Android Librarys Top 100 简介 本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍, 至于排名完全是根据GitHub搜索J ...
- <Android开源库 ~ 1> GitHub Android Libraries Top 100 简介
转载自GitHub Android Libraries Top 100 简介 本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍, 至于排名完全是根据 GitH ...
随机推荐
- 数据库管理工具-Navicat Premium 12
首先感谢下github上大佬,我才能使用这个软件.也可以直接浏览https://github.com/DoubleLabyrinth/navicat-keygen进行安装,非常详细. 1.https: ...
- Linux中条件语句
Linux中备份一个jar包,需要既判断进程是否停止,又判断文件是否存在 1. 进程停了,文件存在则备份 2.进程停了,文件不存在,无需备份 3. 进程在跑,停止进程:文件存在,将文件进行备份 4. ...
- Spring Boot配置多数据源并实现Druid自动切换
原文:https://blog.csdn.net/acquaintanceship/article/details/75350653 Spring Boot配置多数据源配置yml文件主数据源配置从数据 ...
- java线程基础巩固---多Product多Consumer之间的通讯导致出现程序假死的原因分析
在上一次中已经实现一个生产者与消费者的初步模型(http://www.cnblogs.com/webor2006/p/8413286.html),但是当时只是一个生产者对应一个消费者,先贴下代码: p ...
- Light OJ - 1026 - Critical Links(图论-Tarjan算法求无向图的桥数) - 带详细注释
原题链接 无向连通图中,如果删除某边后,图变成不连通,则称该边为桥. 也可以先用Tajan()进行dfs算出所有点 的low和dfn值,并记录dfs过程中每个 点的父节点:然后再把所有点遍历一遍 ...
- 05-Docker私有仓库
一.介绍私有仓库顾名思义,如果我们不想把docker镜像公开放到公有仓库中,只想在部门或团队内部共享docker镜像,这时私有仓库就来了. 二.私有仓库搭建与配置1.拉取私有仓库镜像,这里说明一下,私 ...
- 二、操作XML DOM:XML Document
需要添加的命名空间:using System.Xml; 一.创建xml文件: 1.XmlDocument方式创建 XmlDocument xmldoc = new XmlDocument(); //加 ...
- GITHUB下载源码方式
从昨天开始就想着从GitHub上下载一个开源的Vue的实战项目,希望能从中学习更多的Vue的实用内容,结果搞了半天好不容易下载了,不知道怎么弄.然而,今天终于成功了,激动地我赶紧来记录一下.如何从Gi ...
- 2019-2020-1 20199312《Linux内核原理与分析》第四周作业
计算机和操作系统的法宝 计算机三个法宝 存储程序计算机.函数调用堆栈机制.中断 操作系统:中断中断上下文的切换--保护和恢复现场 进程上下文的切换. Linux源代码目录分析 arch目录:代码量庞大 ...
- docker:设置国内镜像仓储
修改docker仓储镜像 vi /etc/docker/daemon.json 增加下面数据 { "registry-mirrors": ["https://xwx6wx ...