如何通过XML在Android中设置形状的圆角效果?
- 内容介绍
- 相关推荐
本文共计687个文字,预计阅读时间需要3分钟。
Android 的 shape drawable 不支持同时设置全局圆角和单独角度半径。一旦使用了 android:topLeftRadius 这类属性,就必须显式声明所有四个角的样式,否则其他角会默认为 0(即尖角),而不是继承 android:radius 的值。
常见错误现象:android:radius="8dp 写了,又加了 android:topLeftRadius="16dp",结果右下角变成直角,UI 出现不对称。
- 只设全局圆角:用
android:radius,四个角一致 - 要部分圆角:必须全部显式写,未写的角默认为
0dp - 四个角都写但某几个设为
0dp,才是“部分圆角”的正确做法
<shape android:shape="rectangle"> <corners android:topLeftRadius="12dp" android:topRightRadius="12dp" android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" /> <solid android:color="#FF6B6B" /> </shape>
API 21+ 才支持单个角独立设为 0dp
低于 Android 5.0(API 21)的系统,android:bottomLeftRadius="0dp" 这种写法会被忽略,实际仍按默认圆角渲染——也就是老版本里“部分圆角”根本不可靠。
使用场景:如果你的 minSdkVersion ≤ 20,别指望用 corners 做精确的半圆角或切角效果。
- 兼容方案:用
layer-list叠加两个shape,一个全圆角背景 + 一个覆盖直角区域的矩形遮罩 - 更稳妥方案:改用
GradientDrawable或自定义Drawable在代码里生成 - Jetpack Compose 用户直接绕过 XML,用
RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)
android:topLeftRadius 单位必须是 dp,不能用 px 或无单位数字
XML 中所有 radius 属性强制要求带单位,写成 android:topLeftRadius="12" 或 android:topLeftRadius="12px" 都会在编译时报错:Resource value must be a string literal 或运行时崩溃。
容易踩的坑:从设计稿抄数值时漏掉 dp,或者复制粘贴 CSS 圆角习惯写 12px。
- 必须写成
android:topLeftRadius="12dp" - 不支持
sp、pt等其他单位 - 负值非法,
-4dp会导致解析失败
dp,少一个角的声明,或者目标机型太老,都会让效果完全消失。本文共计687个文字,预计阅读时间需要3分钟。
Android 的 shape drawable 不支持同时设置全局圆角和单独角度半径。一旦使用了 android:topLeftRadius 这类属性,就必须显式声明所有四个角的样式,否则其他角会默认为 0(即尖角),而不是继承 android:radius 的值。
常见错误现象:android:radius="8dp 写了,又加了 android:topLeftRadius="16dp",结果右下角变成直角,UI 出现不对称。
- 只设全局圆角:用
android:radius,四个角一致 - 要部分圆角:必须全部显式写,未写的角默认为
0dp - 四个角都写但某几个设为
0dp,才是“部分圆角”的正确做法
<shape android:shape="rectangle"> <corners android:topLeftRadius="12dp" android:topRightRadius="12dp" android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" /> <solid android:color="#FF6B6B" /> </shape>
API 21+ 才支持单个角独立设为 0dp
低于 Android 5.0(API 21)的系统,android:bottomLeftRadius="0dp" 这种写法会被忽略,实际仍按默认圆角渲染——也就是老版本里“部分圆角”根本不可靠。
使用场景:如果你的 minSdkVersion ≤ 20,别指望用 corners 做精确的半圆角或切角效果。
- 兼容方案:用
layer-list叠加两个shape,一个全圆角背景 + 一个覆盖直角区域的矩形遮罩 - 更稳妥方案:改用
GradientDrawable或自定义Drawable在代码里生成 - Jetpack Compose 用户直接绕过 XML,用
RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)
android:topLeftRadius 单位必须是 dp,不能用 px 或无单位数字
XML 中所有 radius 属性强制要求带单位,写成 android:topLeftRadius="12" 或 android:topLeftRadius="12px" 都会在编译时报错:Resource value must be a string literal 或运行时崩溃。
容易踩的坑:从设计稿抄数值时漏掉 dp,或者复制粘贴 CSS 圆角习惯写 12px。
- 必须写成
android:topLeftRadius="12dp" - 不支持
sp、pt等其他单位 - 负值非法,
-4dp会导致解析失败
dp,少一个角的声明,或者目标机型太老,都会让效果完全消失。
