Android圆角与自定义绘制:从clipPath到60fps的实战路径
发布时间:2026/10/26 9:54:41 锦皓数字建站

Android圆角与自定义绘制从clipPath到60fps的实战路径【免费下载链接】awesome-android-uiA curated list of awesome Android UI/UX libraries项目地址: https://gitcode.com/gh_mirrors/aw/awesome-android-ui头像在Figma里是正圆上线变成带白边的椭圆PM在群里你“晚上能修好吗”这个Android圆角的坑你大概率会碰到。awesome-android-ui 收了一堆现成的圆角组件但选之前先搞懂圆角到底怎么画出来的不然库的API看不懂只能怪自己。原理速览圆角到底是怎么画出来的所有圆角的本质都是“裁剪”区别只在裁剪发生在哪一层clipPathCanvas层裁剪。自己构造 RoundRect 路径canvas.clipPath(roundPath)之后画的东西只会出现在路径内。完全可控代价是每帧都要自己维护路径。BitmapShaderPaint层“上釉”。把位图包成 shader 再画形状系统按像素采样图片圆角被预烘进位图滚动时只是贴图。ViewOutlineProviderView层打码。只告诉框架“轮廓是这个形状”裁剪、阴影它自己处理你连 onDraw 都不用进API 21 顺带送阴影。上面这张是仓库里的 Rotatable旋转缩放全走 Canvas 变换——和圆角同一套“绘制层”思路你想露出什么先说清楚裁掉什么。选型决策表先定场景再看库圆角选型不用背先看这张表需求场景推荐方案一句话理由性能代价静态背景ShapeDrawablecorners 属性一行XML搞定零列表里的圆角图BitmapShader 预烘RoundedImageView烘进位图不逐帧计算一次性位图解码跨版本圆角卡片CardView / Outline框架统一管角和阴影轻微图层开销点击半径变化动画自定义View 逐帧Path唯一能逐帧改的办法逐帧CPU建路径异形裁剪clipPath Path全可控星形六边形都行逐帧建路径场景拆解场景A列表圆角图片不掉帧的写法问题一百条的 feed每格一张 96dp 图逐帧 clipPath手指一划40fps。解法别逐帧算预烘。RoundedImageView 把 BitmapShader 那套封装好了直接抄作业com.makeramen.roundedimageview.RoundedImageView android:layout_width96dp android:layout_height96dp app:riv_corner_radius12dp app:riv_border_width1dp app:riv_border_colorcolor/white android:srcdrawable/avatar/列表的写法关键其实在图片装载链路。像 Kiel 这种声明式适配器下图一行数据一行图圆角只是链路最后那 12dp。为什么这么选否决了逐帧 clipPath每帧新路径CPU 不给力和逐格 ShapeDrawableDrawable 不缓存位图布局一变就算一遍。烘成位图之后滚动就是贴图60fps 稳。场景B带阴影圆角卡片的跨版本一致性问题同一张卡片5.0 上圆角干净阴影柔和4.4 上角被切方、阴影发虚。用户不管你的 minSdk只管设计裂没裂。解法角和阴影一起交给框架别自己拼android.support.v7.widget.CardView android:layout_widthmatch_parent android:layout_heightwrap_content app:cardCornerRadius12dp app:cardElevation4dp app:cardPreventCornerOverlaptrue !-- 卡片内容 -- /android.support.v7.widget.CardViewAPI 21 它内部走 Outline阴影由框架画老版本 CardView 会自己退化成位图阴影。同一份布局角是同一个角。为什么这么选否决了 9-patch 阴影手搓每种密度画一张迟早漏一张和纯靠系统 elevation5.0 以下没阴影裸奔。场景C点击时圆角半径变化的交互动画问题关注按钮要从 12dp 胶囊形点击时长成全圆进度环。两个静态 Drawable 来回切是切不出过渡的——半径本身得是个会动的值。解法把圆角半径变成可动画值逐帧重建 PathValueAnimator anim ValueAnimator.ofFloat(12f, getHeight() / 2f); anim.addUpdateListener(v - { cornerRadius (Float) v.getAnimatedValue(); invalidate(); // onDraw 里用新半径重建 RoundRect }); anim.setDuration(180); anim.start();单按钮、180ms、几帧 CPU 建路径无伤大雅。为什么这么选否决 Lottie——它是预制的矢量动画下图顺滑但半径没法跟业务状态成功/失败动态走也否决 9-patch 切换瞬间跳变没有过渡感。性能暗礁⚠️ 三块礁石踩得最多。逐帧建Path→ onDraw 里每帧path.addRoundRect(...)→ 列表滚动每帧16msCPU先扛帧率先掉。硬件加速Xfermode→ Manifest 里android:hardwareAcceleratedfalse→ 硬件加速一关文字渲染全走CPU老机型直接卡。要用 Xfermode 就得认这笔账。嵌套布局做阴影→ CardView 外面再套一层 FrameLayout 画阴影 → 多一层就多一层过度绘制列表滚动时 GPU 翻倍。圆角组件生态速查分三组对号入座图片圆角CircleImageView — 圆形头像最小实现开销几个KBRoundedImageView — 四角半径可独立设列表格子主力SelectableRoundedImageView — 带选中态的版本适合可勾选列表容器圆角CardView — 官方圆角阴影容器跨版本最稳Maskable Layout — 任意Path裁剪子控件clipPath 的容器版MaterialShadows — 跨版本一致的阴影配圆角卡片用异形裁剪ShapeImageView — 图片裁成任意形状圆形星形一把梭android-anyshape — 六边形等多边形几何老师版异形RoundedLetterView — 圆角字母头像没图时的兜底完整清单在仓库 README.md选库前先翻近6个月有没有 commit三年没动的库圆角虽然不会坏依赖迟早坏别赌。仓库可直接克隆git clone https://gitcode.com/gh_mirrors/aw/awesome-android-ui一句话带走把你项目里第一个 ImageView 换成 RoundedImageView滑一下列表感受差距。【免费下载链接】awesome-android-uiA curated list of awesome Android UI/UX libraries项目地址: https://gitcode.com/gh_mirrors/aw/awesome-android-ui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。