views-widgets-samples 之 CardView 实战:在 Android 5.0 支持库中用圆角与阴影构建卡片布局

发布时间:2026/10/15 2:32:05
views-widgets-samples 之 CardView 实战:在 Android 5.0 支持库中用圆角与阴影构建卡片布局
示例工程【免费下载链接】views-widgets-samplesMultiple samples showing the best practices in views-widgets on Android.项目地址https://gitcode.com/gh_mirrors/vi/views-widgets-samples点击查看免费下载CardView 是 Android 5.0API 21时期随 support library 引入的卡片式容器控件为内容提供统一风格的圆角矩形背景与投影阴影。本文以 views-widgets-samples 仓库中的 CardView 示例 为骨架结合其 Java/Kotlin 双版本源码与仪器测试系统讲解 CardView 的布局写法、cardCornerRadius与elevation两大核心属性的作用原理、交互式调节与测试验证方法帮助你直接落地到自己的 Android 项目中。示例概览演示什么、怎么组织CardView 示例的定位非常明确演示 support library 中随 Android 5.0 引入的android.support.v7.widget.CardView控件的基本用法。该声明同时出现在 CardView/README.md 与 base-strings.xml 的应用描述中。从工程结构上看仓库为该示例提供了两个独立可导入的工程目录Java 版默认示例位于 CardView/主代码在 CardView/Application/src/main/java/com/example/android/cardview/ 下Kotlin 版位于 CardViewKotlin/主代码在 CardViewKotlin/Application/src/main/java/com/example/android/cardview/ 下。两个版本的界面与交互完全一致差异仅在语言与测试框架选型上维度Java 版CardViewKotlin 版CardViewKotlin主界面入口CardViewActivity.javaCardViewActivity.kt卡片逻辑承载CardViewFragment.javaCardViewFragment.kt布局文件fragment_card_view.xmlfragment_card_view.xml测试用例SampleTests.java继承ActivityInstrumentationTestCase2SampleTests.ktJUnit4 ActivityTestRuleAndroidJUnit4前置 SDK 要求Android SDK 28 Build Tools v28.0.3Android SDK 27示例运行后呈现一个可交互的演示页页面中央是一张蓝色圆角卡片卡片下方依次是Radius圆角半径与Elevation高度/阴影两个 SeekBar拖动滑块即可实时观察卡片外观变化。这种一个控件 两个属性调节条的极简设计恰好覆盖了 CardView 区别于普通容器的全部核心特性。搭建环境前置条件与构建方式README 明确了构建本示例的三项前置条件Android SDK 28Android Build Tools v28.0.3Android Support Repository提供android.support.v7.widget.CardView所在的 support 库其中 Gradle Wrapper 版本为 6.7.1配置见 CardView/gradle/wrapper/gradle-wrapper.propertiesKotlin 版对应要求 SDK 27。若使用本示例开发环境时的 SDK 版本与上述不完全一致可在 Android Studio 的 SDK Manager 中安装对应版本或自行调整工程的 build 配置。构建方式 README 给出了两条等价路径任选其一即可命令行构建在工程根目录即CardView/或CardViewKotlin/注意 Kotlin 版需使用其自带的 gradlew执行./gradlew build该命令会依次执行编译、打包与测试任务。首次运行会由 Gradle Wrapper 自动下载 6.7.1 发行版并拉取依赖耗时取决于网络状况。Android Studio 导入使用File → Import Project或 Open选中工程根目录由 IDE 基于 settings.gradle内容为include Application识别Application模块并完成同步后即可直接 Run 到模拟器或真机。工程采用单模块结构Application是唯一的 app 模块其入口CardViewActivity已在 AndroidManifest.xml 中声明为带MAIN/LAUNCHERintent-filter 的启动 Activity。界面骨架Activity 承载 Fragment布局定义卡片整个示例采用 Activity 单 Fragment 的经典组织方式。CardViewActivity.java 中onCreate只做两件事设置activity_card_view布局并在savedInstanceState null时即首次创建避免旋转重建后重复添加向R.id.container容器提交CardViewFragment.newInstance()Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_card_view); if (savedInstanceState null) { getFragmentManager().beginTransaction() .add(R.id.container, CardViewFragment.newInstance()) .commit(); } }容器布局 activity_card_view.xml 只是一个带四边 16dp 内边距的FrameLayout边距值定义在 dimens.xml 的activity_horizontal_margin/activity_vertical_margin。真正的卡片界面在 fragment_card_view.xml 中外层是ScrollView内部为垂直LinearLayout依次包含一个 CardView 与两个标签 SeekBar水平行。Kotlin 版 fragment_card_view.xml 结构相同差异仅在把硬编码的100dp圆角半径/高度抽成了 card_elevation 与 card_radius 尺寸资源。核心CardView 布局写法与两大关键属性CardView 的声明方式与普通 ViewGroup 无异关键在于它独有的两个属性。示例中的完整声明如下摘自 fragment_card_view.xmlandroid.support.v7.widget.CardView android:idid/cardview android:layout_widthfill_parent android:layout_heightwrap_content android:elevation100dp card_view:cardBackgroundColorcolor/cardview_initial_background card_view:cardCornerRadius8dp android:layout_marginLeftdimen/margin_large android:layout_marginRightdimen/margin_large TextView android:layout_widthwrap_content android:layout_heightwrap_content android:layout_margindimen/margin_medium android:textstring/cardview_contents / /android.support.v7.widget.CardView两个注意点需要特别说明自定义属性命名空间cardCornerRadius、cardBackgroundColor属于 CardView 自定义属性必须使用http://schemas.android.com/apk/res-auto命名空间即card_view:前缀见布局根元素的xmlns:card_view声明而不是android:前缀android:elevation使用系统命名空间阴影高度即 Android 5.0 引入的 Material Design 海拔elevation概念因此走系统属性通道。下面逐一拆解 CardView 的属性与作用原理。cardCornerRadius圆角半径card_view:cardCornerRadius控制卡片四角的圆角弧度示例初始值为8dp。这个值直接影响背景绘制的Path圆角矩形形状同时也决定了内容裁剪的边界。在示例的交互逻辑中CardViewFragment.java 为 Radius SeekBar 注册了监听器滑块每次变化都调用mCardView.setRadius(progress)progress 取值为 SeekBar 的进度值0 到滑块上限单位实际被当作 dp 的浮点值使用mRadiusSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { Log.d(TAG, String.format(SeekBar Radius progress : %d, progress)); mCardView.setRadius(progress); } ... });对应 Kotlin 版则使用属性语法cardView.radius progress.toFloat()见 CardViewFragment.kt。特别提醒示例中setRadius(progress)传入的是整型 progress实际以 dp 语义参与绘制——这一点从布局中cardCornerRadius8dp的初始值和 SeekBar 交互可见在自己的项目中应使用setRadius(dp2px(...))之类的 dp→px 换算或直接使用cardCornerRadius的 dp 资源以免在不同密度屏幕上出现偏差。elevation阴影高度海拔android:elevation是 Material Design 中通过 Z 轴海拔产生投影的核心属性海拔越高卡片下方投影越深、越柔和、范围越大。示例布局中给出了一个演示性的较大初始值100dpCardViewFragment.java 中对应的 Elevation SeekBar 监听器则调用mCardView.setElevation(progress)mElevationSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { Log.d(TAG, String.format(SeekBar Elevation progress : %d, progress)); mCardView.setElevation(progress); } ... });Kotlin 版对应cardView.elevation progress.toFloat()。这里有一个值得展开的原理性细节CardView 是少数同时打通了绘制阴影与硬件渲染的 support 库控件。从源码结构看CardView 在 Lollipop 及以上系统通过 elevation 使用原生阴影渲染在低版本系统则回退到自绘阴影实现它的setElevation方法即示例调用的入口会同步更新背景层与阴影层setRadius则会重算背景RoundRectDrawable的形状并联动裁剪内容。示例通过两个 SeekBar 让你直观地看到圆角只影响卡片外形阴影随 elevation 变化——二者是独立可调的两个维度。cardBackgroundColor卡片背景色card_view:cardBackgroundColor设置卡片背景色。示例通过 colors.xml 定义了初始背景色cardview_initial_background #71C3DE浅蓝色使圆角与投影效果在演示中一目了然。若不设置CardView 会使用主题默认的背景色。交互与验证测试用例如何锁死行为CardView 示例的一个亮点在于它把SeekBar 调节圆角/高度这一交互写成了可自动验证的仪器测试这既是示例质量的保证也是理解setRadius/setElevation语义的绝佳教材。Java 版 SampleTests.java 继承自ActivityInstrumentationTestCase2CardViewActivity共三个用例testPreconditions断言 Activity、Fragment 以及两个 SeekBar 均已正确创建依赖mRadiusSeekBar、mElevationSeekBar字段因此源码中为它们标注了VisibleForTestingtestRadiusSeekbarChangesRadiusOfCardView在主线程中把 Radius SeekBar 进度设为 50随后断言mCardView.getRadius()等于 50.0f——证明滑块变化确实写入了 CardView 的圆角值testElevationSeekbarChangesElevationOfCardView同理把 Elevation SeekBar 设为 40断言getElevation()返回 40.0f——证明高度属性随滑块联动。public void testRadiusSeekbarChangesRadiusOfCardView() { getInstrumentation().runOnMainSync(new Runnable() { Override public void run() { float radius 50.0f; mFragment.mRadiusSeekBar.setProgress((int) radius); assertEquals(radius, mFragment.mCardView.getRadius()); } }); }由于getRadius()返回的是 px 值而进度值以 dp 语义传入因此在默认密度mdpi1dp 1px设备上二者直接相等。该测试也侧面印证了前文progress 以 dp 语义参与绘制的推断。Kotlin 版 SampleTests.kt 则升级为 JUnit4 风格RunWith(AndroidJUnit4::class)ActivityTestRule测试逻辑与 Java 版一一对应。两套测试放在一起阅读正好可以对照学习 Instrumentation 测试从ActivityInstrumentationTestCase2到ActivityTestRule的演进写法。主题与资源组织让卡片融入 App 视觉体系示例还展示了如何让 CardView 与应用的 Material 主题协同。看 template-styles.xml 与 values-v21/base-template-styles.xml默认低版本下Theme.Base继承android:Theme.Light而在 API 21 的values-v21限定目录下则改为继承android:Theme.Material.Light。也就是说示例在 Android 5.0 及以上设备上使用真正的 Material 主题在低版本设备上退化为兼容主题——这与 CardView 本身新系统原生渲染、旧系统兼容渲染的设计哲学是一致的。资源的组织也值得借鉴字符串卡片说明文案、两个 SeekBar 的标签集中在 strings.xml含cardview_contents中对android:elevation与card_view:cardCornerRadius用法的说明性文本尺寸集中在 dimens.xml颜色集中在 colors.xml主题样式则通过values-sw600dp、values-v11、values-v21等限定目录按屏幕与版本差异化提供。迁移到 AndroidX 与 Material 时代的实战建议最后给出一条面向现代工程实践的衔接建议基于仓库事实的延伸解读本示例发布于 Android 5.0 support library 时代使用的是android.support.v7.widget.CardView。如今 Android 工程普遍迁移到 AndroidX对应类是androidx.cardview.widget.CardView核心属性与 API 一一对应cardCornerRadius、cardBackgroundColor、elevation、setRadius()、setElevation()因此本示例中的布局写法与交互逻辑几乎可以无痛平移若追求更现代的 Material 风格卡片可进一步参考 Material Components 的MaterialCardView支持描边、按压态、选中态等增强能力。需要说明的是这些扩展能力不在本仓库范围内迁移时请以目标依赖库的官方文档为准。小结围绕 CardView/README.md 这份仅数百字节的示例说明结合仓库中的双版本实现可以提炼出 CardView 的完整知识闭环是什么Android 5.0 引入、由 support library 提供的卡片容器自带圆角与投影怎么配card_view:cardCornerRadius控制圆角、android:elevation控制阴影、card_view:cardBackgroundColor控制背景自定义属性必须走res-auto命名空间怎么验证参考 SampleTests.java / SampleTests.kt 的仪器测试写法用 SeekBar 驱动setRadius/setElevation并断言getRadius/getElevation的返回值。对希望在列表、详情页或信息流中快速获得统一卡片视觉的开发者而言CardView 至今仍是最低成本的方案之一而这份示例的价值在于它把圆角 阴影两个抽象概念变成了可拖动、可测试、可对照源码的具体工程。赞分享示例工程【免费下载链接】views-widgets-samplesMultiple samples showing the best practices in views-widgets on Android.项目地址https://gitcode.com/gh_mirrors/vi/views-widgets-samples点击查看免费下载相关推荐如何用跨平台资源下载工具轻松捕获网络资源完整指南如何用跨平台资源下载工具轻松捕获网络资源完整指南 还在为无法保存喜欢的在线视频而烦恼吗想要下载无水印内容却找不到合适的工具今天我要介绍的跨平台资源下载工具桌面应用网络音视频推荐使用Android Shadow Layout —— 超越 CardView 的阴影效果库推荐使用Android Shadow Layout —— 超越 CardView 的阴影效果库 项目介绍 在移动应用开发中视觉效果常常是提升用户体验的关键因Android Material Design 列表与卡片实战RecyclerView 与 CardView 完整使用指南Android Material Design 列表与卡片实战RecyclerView 与 CardView 完整使用指南 本篇指南基于 Android 官方文档教程移动开发上一篇X. 论文标题 ![](https://img.shields.io/badge/2024-CVPR-green)下一篇终极指南co异步控制流库的核心函数与参数详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考