当前位置: 首页 > news >正文

进阶实战:基于android_maskable_layout 源码扩展自定义遮罩ViewGroup的完整指南

进阶实战:基于android_maskable_layout 源码扩展自定义遮罩ViewGroup的完整指南

【免费下载链接】android_maskable_layoutA library that easily allows you to mask layouts/viewgroups项目地址: https://gitcode.com/gh_mirrors/an/android_maskable_layout

android_maskable_layout 是一款轻量级的 Android 遮罩布局开源库,它允许开发者通过简单的 XML 属性或一行代码,为任意 View 和 ViewGroup 添加圆形、星形甚至动画遮罩效果。本文将从源码角度剖析其核心实现,并给出 3 个可落地的扩展方案,帮助你从「会用」进阶到「会改」,打造属于自己的自定义遮罩 ViewGroup。无论你是刚接触 Android 自定义 View 的新手,还是想提升 UI 表现力的普通开发者,这份实战指南都能让你快速上手。

android_maskable_layout 是什么:一个给 ViewGroup 加遮罩的轻量级库

简单来说,android_maskable_layout只做了一件事:把任意 ViewGroup 变成一块「画布」,再用一张遮罩图(Drawable)去裁剪它的子 View 显示区域。它的核心类MaskableFrameLayout继承自系统FrameLayout,因此任何原本能放进 FrameLayout 的布局和控件,都能直接获得遮罩能力。

它的典型使用方式是在 XML 中声明,几乎零代码侵入:

<com.christophesmet.android.views.maskableframelayout.MaskableFrameLayout android:layout_width="100dp" android:layout_height="100dp" app:mask="@drawable/masking_masking_20" app:porterduffxfermode="DST_IN"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/unicorn"/> </com.christophesmet.android.views.maskableframelayout.MaskableFrameLayout>

对比上面的演示动图就能直观看到:同样一张独角兽图片,无遮罩时是矩形,加上圆形遮罩就变圆,加上星形遮罩就变星形,甚至还能加载 60 帧的逐帧动画遮罩。

核心原理速览:MaskableFrameLayout 源码到底做了什么

扩展自定义遮罩 ViewGroup 之前,先花 3 分钟看懂源码。整个库的核心只有两个文件:

  • 核心类:library/src/main/java/com/christophesmet/android/views/maskableframelayout/MaskableFrameLayout.java
  • 自定义属性:library/src/main/res/values/attrs_maskable_framelayout.xml

第一步:把遮罩 Drawable 转成 Bitmap

遮罩本质上是一张与 View 同尺寸的位图。在makeBitmapMask()方法中,库会把传入的 Drawable 绘制到一个ARGB_8888的 Bitmap 上。关键前提是 View 必须先完成测量(宽高大于 0),所以库通过ViewTreeObserver注册了全局布局监听,等尺寸确定后再生成遮罩。

第二步:用 PorterDuff 混合模式完成裁剪

遮罩的显示发生在重写dispatchDraw(Canvas)中(MaskableFrameLayout.java第 207-216 行):先绘制所有子 View,再把遮罩 Bitmap 以指定的PorterDuffXfermode混合上去。默认使用DST_IN,即「保留子 View 中与遮罩重叠的部分」,从而实现形状裁剪。

第三步:通过三个自定义属性控制行为

属性文件定义了mask(遮罩 Drawable)、porterduffxfermode(17 种混合模式枚举)和anti_aliasing(抗锯齿开关),全部通过TypedArray在构造时读取。

扩展前的准备工作:下载源码与工程结构

首先获取源码:

git clone https://gitcode.com/gh_mirrors/an/android_maskable_layout

工程采用多模块结构,settings.gradle中声明了librarySample两个模块,结构清晰:

android_maskable_layout/ ├── library/ # 核心库模块(AAR) │ └── src/main/java/com/christophesmet/android/views/maskableframelayout/ │ └── MaskableFrameLayout.java # 全部核心逻辑 └── Sample/ # 演示工程 ├── MainActivity.java # 动画遮罩触发逻辑 └── res/drawable/animation_mask.xml # 60帧逐帧动画遮罩

建议先运行 Sample 模块查看效果,再进入源码研读,效率更高。

三个实战扩展方向:打造你的自定义遮罩 ViewGroup

扩展一:运行时动态更换遮罩形状

原库的 XML 配置是静态的,但setMask()方法支持运行时热更新。你可以继承MaskableFrameLayout并封装自己的 API,比如点击按钮在圆形、星形之间切换:

// 子类中提供公开方法 public void applyCircleMask() { setMask(R.drawable.masking_masking_01); // 圆形遮罩 } public void applyStarMask() { setMask(R.drawable.masking_masking_20); // 星形遮罩 }

注意setMask()内部会自动重建 Bitmap 并调用invalidate(),无需手动刷新。

扩展二:让遮罩动起来——AnimationDrawable 动画遮罩

这是本库最亮眼的特性:遮罩本身可以是一段逐帧动画。Sample 中的animation_mask.xml是一个包含 60 帧 PNG 的animation-list(每帧 18ms),源码通过setCallback(this)注册为 View 的 Callback,并重写invalidateDrawable()scheduleDrawable()驱动动画刷新。

在你的自定义遮罩 ViewGroup 中,可以像 Sample 的MainActivity一样主动触发动画:

Drawable drawable = getDrawableMask(); if (drawable instanceof AnimationDrawable) { AnimationDrawable anim = (AnimationDrawable) drawable; anim.stop(); anim.start(); // 遮罩形状开始逐帧变化 }

基于这个思路,你甚至可以用Animator驱动形状渐变,实现「呼吸」或「波纹」等更复杂的动效。

扩展三:借助 PorterDuff 模式玩出更多视觉效果

除了裁剪用的DST_IN,库还支持 17 种混合模式(attrs_maskable_framelayout.xml中已定义枚举)。在扩展时调用setPorterDuffXferMode()即可随时切换:

setPorterDuffXferMode(PorterDuff.Mode.DST_OUT); // 挖空效果 setPorterDuffXferMode(PorterDuff.Mode.MULTIPLY); // 正片叠底 setPorterDuffXferMode(PorterDuff.Mode.SCREEN); // 滤色提亮

比如用DST_OUT实现圆形挖孔,配合底层阴影即可做出「异形头像卡片」等高级 UI。

自定义遮罩 ViewGroup 时的三个避坑要点

坑一:必须使用软件层绘制。源码构造方法中调用了setLayerType(LAYER_TYPE_SOFTWARE, null),因为PorterDuffXfermode依赖软件渲染。如果你的自定义 ViewGroup 关闭了软件层,遮罩会直接失效——这是最常见的「为什么没效果」原因。

坑二:宽高为 0 时遮罩静默失败。makeBitmapMask()在宽高不大于 0 时只打日志并返回 null。所以避免在wrap_content且无子 View 的情况下使用,并留意日志中的Can't create a mask提示。

坑三:遮罩 Bitmap 会频繁重建,注意内存回收。源码在onSizeChanged时重建遮罩,并在swapBitmapMask()中回收旧 Bitmap。扩展时若自行持有遮罩引用,务必按相同方式管理,防止内存抖动。

写在最后

从「改一行属性」到「读懂核心源码」,android_maskable_layout 是一个非常适合练习自定义 View 的小而美项目。掌握了它的 Bitmap 遮罩 + PorterDuff 混合模式这两大核心思想,你就拥有了扩展出任意形状、任意动画、任意混合效果的自定义遮罩 ViewGroup 的能力。希望这份完整指南能帮你少踩坑、快上手,写出更精致的 Android 界面。

【免费下载链接】android_maskable_layoutA library that easily allows you to mask layouts/viewgroups项目地址: https://gitcode.com/gh_mirrors/an/android_maskable_layout

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.jsqmd.com/news/1405466/

相关文章:

  • iOS越狱终极完整指南:从机型确认到插件安装的保姆级全流程
  • 2026 年 8 月更新:太原代理记账公司哪家靠谱?5 家正规机构盘点,附实用避坑指南 - 山西融纳集团
  • 臻品玉源玉器行:16载深耕和田玉的直营专业服务商 - 互联网科技品牌测评
  • 潮州湘桥 2026 靠谱防水补漏|本地实体房屋渗漏检测维修服务商 - 超人防水
  • 国产图像传感器芯片崛起,改写具身智能格局
  • 零基础深耕商业摄影:从踩坑迷茫到高薪就业的完整求学实录 - 职业学校推荐官
  • 攀枝花市正规防水补漏公司 (2026 新) 地下室漏水:本地专业团队推荐,解决老房新屋渗水难题 - 用户198513
  • Visual Components碰撞检测精度能满足焊接产线吗?
  • 深入 SmartBugs 源码:从 CLI 参数到 Docker 任务调度的执行全流程
  • HyperNetX 数据互操作指南:HIF 超图交换格式与 XGI、HGX 跨库协作
  • 2026新疆和田玉品牌推荐:国石玉源等3家**企业实测对比 - 互联网科技品牌测评
  • 一条命令解密 PyInstaller 打包 exe:PyInstaller 逆向分析入门与 PyInstxtractor 使用教程
  • OpenMower配置大全:mower_config环境变量逐项详解(含NTRIP/RTK关键参数)
  • 2026年08月广东省化妆品展柜工艺实测手册:10大质量通病溯源与标准化验收指南
  • GTA5线上小助手免费使用教程:一款快速提升游戏体验的全能辅助工具
  • 想在网页里剪视频?这个React视频编辑组件三步就能上手
  • FastCSV 3.x 升级 4.x 完整指南:10 个破坏性变更逐个击破
  • FSearch 极速文件搜索工具全攻略:让 Linux 文件查找快如闪电
  • DMA
  • 2026年GEO优化企业内训机构全维度选型指南:10家合规服务商盘点+签约避坑全维度FAQ - U渠道
  • 2026北京救护车出租服务推荐,失能老人跨省返乡安全要点 - 产品推荐官
  • 2026年8月朝阳外墙漏水维修靠谱渠道盘点,高层高空渗水修缮避坑指南 - 聪居到家
  • AXPhotoViewer 性能优化:预取机制与内存管理如何支撑千图流畅浏览
  • 银行数据自动同步:Transity 脚本一键抓取 DKB、PayPal 等多家银行账单
  • 2026安防产品出口企业GEO优化服务商盘点:靠谱机构甄选攻略与避坑指南 - 商业大观
  • 太原苹果手机换电池换屏(2026太原永健手机经销部版) - 滚动商讯
  • sbt-scoverage 排除机制实战:3 招精准跳过类、包与文件
  • AXPhotoViewer 项目解读:一个值得铭记的 iOS 开源项目与维护者故事
  • 源城 2026 河源宅仕达防水补漏本地实体房屋渗漏检测维修服务商 - 超人防水
  • 2026年编织带**:余姚50mm编织带为何稳居前列? - 米諾