GIF图圆角3行代码背后大有乾坤:MeiWidgetView的CornersGifView原理详解
【免费下载链接】MeiWidgetView🔥一款汇总了郭霖,鸿洋,以及自己平时收集的自定义控件集合库(小红书)项目地址: https://gitcode.com/gh_mirrors/me/MeiWidgetView
在 Android 开发中,给 GIF 动图加圆角是个经典难题。开源控件集合库MeiWidgetView中的CornersGifView(GIF图圆角控件)只需要 3 行代码就能让任意 GIF 拥有漂亮的圆角,支持四个角独立设置圆角半径。本文将带你从零理解它的实现原理:为什么 GIF 不能像普通图片一样直接圆角?Path的逆向填充模式又是如何"画"出圆角的?🎨
一、3行代码快速上手 GIF 圆角控件
先看看使用有多简单。在布局文件中声明CornersGifView并设置cornerSize即可:
<com.meis.widget.corners.CornersGifView android:id="@+id/iv_gif" android:layout_width="wrap_content" android:layout_height="wrap_content" app:cornerSize="8dp" />然后像普通ImageView一样加载 GIF 图(官方 Demo 用 Glide 加载):
Glide.with(this).load(R.mipmap.gif_01).asGif().into(mGifImageView);就这三行核心代码。但它内部隐藏了不少巧思,下面逐一拆解。
上图:MeiWidgetView 中图片控件应用圆角效果后的展示效果
二、为什么 GIF 不能直接套圆角裁剪?
普通静态图片加圆角,通常用setClipPath裁剪一张带圆角的Bitmap。但 GIF 的本质是连续播放的多帧画面,每一帧都重新解码、重新绘制,对静态位图的裁剪对动态帧并不生效——这也是很多"静态图圆角成功、GIF 圆角失败"的原因。
CornersGifView 换了个思路:👉不裁剪图片,而是把圆角之外的区域"盖住"。用控件自身的背景色,在图片四角画出"补角"色块,视觉上就形成了圆角。这个"遮罩盖角"方案对静态图和 GIF 通吃。
三、核心原理拆解:逆向填充 + 圆角路径
核心实现全部在 CornersGifView.java,共分为四个关键点:
1. 逆向填充模式:让"圆角外"自动被着色
控件在构造时就设置了一个关键的填充模式:
mPath.setFillType(Path.FillType.INVERSE_EVEN_ODD);INVERSE_EVEN_ODD(逆向偶奇填充)的意思是:路径围成的区域之外才填充颜色。所以只要往Path里加一个圆角矩形,绘制时自动会把矩形外、控件内的四个角填充成画笔颜色——圆角效果就此产生。✨
2. onSizeChanged 时机构建圆角路径
在 addRoundRectPath 方法 中,控件在尺寸变化时把视图范围封装成圆角矩形加入Path,四个角的半径来自mCorners数组(顺序为左上、右上、右下、左下)。
3. 背景色"黑科技":反射自动取色
盖角需要一个颜色,直接写死白色显然不专业。getPaintColor 方法 做了一套完整的取色策略:
- 向上逐级遍历父视图,找到第一个有背景色的 View;
- 通过反射读取
ColorDrawable内部的mColorState → mUseColor字段拿到真实颜色(因为ColorDrawable没有公开的颜色 getter); - 父链全部透明时,回退读取主题中的
colorBackground作为兜底色。
这样无论控件放在什么页面,盖色都与页面背景融为一体,圆角过渡几乎无感。🤔
4. onDraw 中补刀绘制
onDraw 方法 先调用super.onDraw(canvas)完成 GIF 的正常绘制,再用canvas.drawPath(mPath, mPaint)把四角"补"上。顺序不能颠倒,否则 GIF 就被盖住了。
四、四个角独立控制:自定义属性与动态调节
控件在 attrs.xml 中声明了 5 个属性:cornerSize(四角统一)以及leftTopCorner、leftBottomCorner、rightTopCorner、rightBottomCorner(四角独立)。
对应的 XML 示例见 corners_gif_activity.xml,其中app:cornerSize="8dp"就是那"3行代码"的关键属性。
官方 Demo MeiCornersGifActivity.java 还放了 4 个SeekBar,拖动滑条实时调用setLeftTopCorner(progress)等方法,动态调节每个角的半径——内部会重建Path并invalidate()重绘,可以直观看到圆角平滑变化的过程,非常适合用来理解Path与重绘的关系。
五、使用小贴士与总结
✅使用建议:
- 控件继承自
AppCompatImageView,所有ImageView的用法(缩放类型、Glide/Fresco 加载)均可照用; - 圆角半径支持运行时修改,无需重新布局;
- 若页面背景是纯色,盖色自动匹配;若背景是图片/渐变,建议给父布局设置纯色背景,避免四角露出穿帮。
📌总结:CornersGifView 用最少的代码解决了 GIF 圆角这个高频痛点——不裁剪、只遮盖,靠INVERSE_EVEN_ODD逆向填充 +addRoundRect圆角路径 + 反射取背景色三板斧组合而成。理解了"逆向填充"和"绘制顺序"这两个知识点,你也可以轻松举一反三,做出圆形头像、胶囊按钮等各类裁剪效果。
更多同类自定义控件(小红书标签拖拽、图片裁剪、贝塞尔点赞等)的源码与 Demo,可在本仓库 widget 模块 中继续探索,配合 README.md 中的各控件效果说明,是学习 Android 自定义控件的宝藏素材库。🚀
【免费下载链接】MeiWidgetView🔥一款汇总了郭霖,鸿洋,以及自己平时收集的自定义控件集合库(小红书)项目地址: https://gitcode.com/gh_mirrors/me/MeiWidgetView
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考