Android 点九图机制讲解及在聊天气泡中的应用
点九图简介
Android为了使用同一张图作为不同数量文字的背景,设计了一种可以指定区域拉伸的图片格式“.9.png”,这种图片格式就是点九图。
注意:这种图片格式只能被使用于Android开发。在ios开发中,可以在代码中指定某个点进行拉伸,而在Android中不行,所以在Android中想要达到这个效果,只能使用点九图(下文会啪啪打脸,其实是可以的,只是很少人这样使用,兼容性不知道怎么样,
点九图实质
点九图的本质实际上是在图片的四周各增加了1px的像素,并使用纯黑(#FF000000)的线进行标记,其它的与原图没有任何区别。可以参考以下图片:
标记位置 | 含义 |
---|---|
左-黑点 | 纵向拉伸区域 |
上-黑点 | 横向拉伸区域 |
右-黑线 | 纵向显示区域 |
下-黑线 | 横向显示区域 |
点九图在 Android 中的应用
点九图在 Android 中主要有三种应用方式
- 直接放在 res 目录中的 drawable 或者 mipmap 目录中
- 放在 assert 目录中
- 从网络下载
第一种方式是我们最常用的,直接调用 setBackgroundResource
或者 setImageResource
方法,这样的话图片及可以做到自动拉伸。
而对于第二种或者第三种方式,如果我们直接去加载 .9.png,你会发现图片或者图片背景根本无法拉伸。纳尼,这是为甚么呢。下面,且听老衲慢慢道来。
Android 并不是直接使用点九图,而是在编译时将其转换为另外一种格式,这种格式是将其四周的黑色像素保存至Bitmap类中的一个名为 mNinePatchChunk
的 byte[] 中,并抹除掉四周的这一个像素的宽度;接着在使用时,如果 Bitmap 的这个 mNinePatchChunk
不为空,且为 9patch chunk,则将其构造为 NinePatchDrawable
,否则将会被构造为 BitmapDrawable,最终设置给 view。
因此,在 Android 中,我们如果想动态使用网络下载的点九图,一般需要经过以下步骤:
- 使用 sdk 目录下的 aapt 工具将点九图转化为 png 图片
- 解析图片的时候,判断是否含有 NinePatchChunk,有的话,转化为 NinePatchDrawable
public static void setNineImagePatch(View view, File file, String url) { if (file.exists()) { Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); byte[] chunk = bitmap.getNinePatchChunk(); if (NinePatch.isNinePatchChunk(chunk)) { NinePatchDrawable patchy = new NinePatchDrawable(view.getResources(), bitmap, chunk, new Rect(), null); view.setBackground(patchy); } } }
点九图上传服务器流程
aapt 转换命令
单个图片文件转换
./aapt s -i xxx.9.png -o xxx.png
批量转换
# 批量转换 ./aapt c -S inputDir -C outputDir # inputDir 为原始.9图文件夹,outputDir 为输出文件夹
执行成功实例