我记得上一次接触 .9图,还是在刚入行没多久那会儿(2017),当时知道 .9图可以防止因为图片变形,主要涉及到多机型适配场景;最近闲来无事又过了一次《第一行代码》,又看到了 .9图,所以想着记录一下那年尚未完全掌握的知识
我一般学习一样的技术的时候,都会先翻一些文章,然后自己写个Demo,最后没问题的话总结一篇Blog,记录我学习中遇到的问题和思考
嗯… 其实挺多UI可能并不了解.9
图,所以有时候她们可能也无法提供.9
图,所以最好是自己掌握这种技巧,能让你在开发中应付自如
效果
在写完这篇 blog
不久后,正好遇到了一个业务需求用到了.9
图,特此补充了一种实战效果
Demo 前后效果
嗯… 正常的话,这个应该放在下方的;但是为了方便确定你想学的 和 我想讲的是不是一个事物
,提前将Demo效果放置一番
项目 实战效果
图中红色边框内的数据是可变的(随机1-N条)
,但是设计给的背景图是固定高度
的,那么当数据较少时,布局并不会自适应而是固定高度,然后看起来就会非常丑
!
那么我们该如何处理?
Hint
:已知背景图有圆角+渐变效果,并非纯色背景,所以 android:layout_height="wrap_content"
并不完全适用于此
假设背景图原始高度为100px,我让设计帮我切一张50px的背景图,然后做一张.9图,让其自动拉伸
,即可完美实现业务&设计需求
基础认知
什么是 .9 图? 9patch图?
Andriod app 开发中一种特殊的图片形式,文件的扩展名为:.9.png
.9 图有什么作用?
在图片拉伸的时候保证其不会失真。让图片在指定的位置拉伸和在指定的位置显示内容,这样图片的边边角角就不会出现失真
不知道你有没有想过这个问题:.9图仅仅是为了适配么?我直接进行图片适配不好么?
我在 9_patch图 - 意义重大 找到了比较认同的一些观点
1)自适应分辨率,减小apk包体积
:一张可以自动拉伸不会变形的.9图即意味着可以做到自适应,那么我们就不必要为每个分辨率做一套图标,原本需要适应分辨率的几张图片只用一张自适应分辨率的.9图即可,减少图片使用,这对减小包体积意义非凡;
(上百个类文件占1M顶天了,72*72分辨率的小图标,不压缩200KB一张,一张小图标抵20个类文件毫不夸张,尽量减少图片的使用绝对是减小APK体积的一大利器)
2)减小apk包体积
:单张.9图大小小于原始PNG图片。
使用时有没有注意的东西?
.9图
一定要放在drawable
里.9图
片要设置在background
里才会生效ImageView
里的src
里设置是无效的...无效的...无效的...
- 当制作的点9图片本身png就足够大的时候,你画了拉伸区域(这个时候确定了不拉伸区域);如果你
不拉伸区域里有logo
,当你放置这个点9图片的时候,他还是会变形,变形,变形
。原因是自身图片太大,放置在比较小控件的background时,拉伸区域缩到0是,未拉伸区域的大小还大于控件的大小区域,自然会变形,给人一种点9图片不生效的感觉
。
嗯… 我琢磨了下,可能偶尔还能秀秀技能,好了来看看 .9图 在As的显示样式
吧
这张图我们让他支持拉伸不变形,同时不影响底部的小图标(小图标主要体现在纵向显示内容的设置
)
- 左侧:当前.9图,可直接制作
- 右侧:当制作 .9图后,
不同方向的拉伸效果
主要看一下制作 .9图时应该注意什么,具体先以下图为例
每一张.9图,四边都有黑线,意义稍有不同
在正式学习之前我认为四条黑线的意义是这样的…(错误认知!!!
)
下面俩点是错误的惯性思维
- 上下俩侧黑线,代表 横向拉伸范围
- 左右俩侧黑线,代表 纵向拉伸范围
正确认知(看过来~~~~~~)
- 默认右侧、下侧都自带黑线;这代表的内部
内容的显示范围
,大部分场景拉满就行; 左侧黑线
,代表纵向拉伸范围
上侧黑线
,代表横向拉伸范围
右侧黑线
,代表纵向内容显示区域
下侧黑线
,代表横向内容显示区域
直接看图吧, 来源于此
As 制作 .9
图时有些便捷小工具
可以使用
这样看着方便一些(我一般都全选)
Zoom
:左边原图的缩放比例
Patch scale
:右边点9图缩放后的效果
show lock
:鼠标放到原图上,会显示红色斜线部分
。表示点9图锁定的区域
show content
:是右边图中蓝色部分,蓝色表示可以填充内容
,白色便是不可填充内容,移动原图中右边和下边的修改可填充内容的区域,规则如上show patches
:显示原图中可以缩放的区域
,如上图绿色和紫色部分
- 左边
原图的粉色区域是可拉伸的区域
- 右边
预览图,分别是纵向拉伸,横向拉伸,扩展拉伸
,紫色区域就是拉伸了的区域
准备工作
我想了想,使用.9图频繁点的场景对话框背景
应该算一个,所以我去 iconfont 先下载了俩个背景图
材料准备好了,那么需要用到了 .9图的 制作工具 - draw9patch
,正常情况下该工具位于 Android SDK/tools
目录,也就是 draw9patch.bat
,双击即可打开
嗯… 我看了看我 tools 工具目录下并木有 draw9patch.bat
(哭笑不得),所以我想:
.9图工具
可能是Sdk安装时的选项安装
,我当时并无选取- 新版Sdk默认
兼容
了.9图工具
- 新版Sdk默认
去除
了.9图工具
提醒
:因为我做的 .9 图是聊天框样式,我看也有的是用 .9图
做以下 圆角效果 的,其实这种图可以直接用shape画
在 圆角效果 的介绍中,我学习了到了一个小知识: .9图
,就是将图片横向和纵向随意进行拉伸,却可以保留像素的精细度、渐变质感和圆角的大小(圆角大小持保留态度)不发生变化,以实现多分辨率下的完美显示效果
。
因为 制作.9图的方式不是仅此一种
,来看看我查到的制作方式有哪些,顺便说说我的感觉~
- 最懒人的方式就
让UI提供.9图
,但有的UI可能并不会,而且效果不好需要多次修改...
(推荐性:一般
) - 在
Eclipse
中有提供专门的工具来制作.9图片;在sdk目录下的tools目录,有一个叫做draw9patch.bat
的文件,双击打开就可以使用。(Look Here:讲的还是SDK/Tools 提供的draw9patch.bat,可忽略该方式!!!
) - 使用
AndroidStudio
直接创建 .9图,方便修改、测试(推荐
- 该篇所用方式)
制作 .9图
为了防止你跳着看,说明一下.9图使用注意项
.9图
一定要放在drawable
里.9图
片要设置在background
里才会生效- 通过
ImageView
设置src
属性是无效的...无效的...无效的...
把之前准备做 .9 图的原图放在 drawable
接下来要创建 .9图
,创建流程:选择原图 → 右键 → Create 9-patch file
,也要放在drawable
不显示 Create 9-patch file ,你需要看看原图是不是png格式!!!
.9图的命名不可与原图名称相同,否则在引用时会报错!!!
创建的时候直接定义好 .9图
名字就好,.9图在As内会自定显示 .9.png
(.9图名字别和原图名称一样,不然无法识别出来!!!
)
根据之前讲的方式,四边画线;如果画错了的话,直接Shift + 左键
消除就行;最后记得保存,可以直接Ctrl + S
最后看下我做的图和原图的对比效果
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="90dp"
android:background="@drawable/talk_center_befroe_bg"
android:gravity="center"
android:text="原图" />
<TextView
android:layout_width="match_parent"
android:layout_height="90dp"
android:background="@drawable/talk_center_after_bg"
android:gravity="center"
android:paddingHorizontal="5dp"
android:text="已做 .9 图处理" />
<TextView
android:layout_width="match_parent"
android:layout_height="90dp"
android:background="@drawable/talk_right_before_bg"
android:gravity="center"
android:text="原图" />
<TextView
android:layout_width="match_parent"
android:layout_height="90dp"
android:background="@drawable/talk_right_after_bg"
android:gravity="center"
android:text="已做 .9 图处理" />
</LinearLayout>
所遇错误
仅记录目前我所遇到的问题,如您有遇到有意思的问题,也可以评论留言
多段划线
在左上(横纵)可分段划线(延伸)
在右下(横纵)不可分段划线(显示内容),编译直接报错!!!
安全检查
AS早期可能对 .9图
增加了安全检查机制
,有不规范的地方可能会给你编译报错(这是很多年前的一篇
blog看到的,现在应该不会有这个问题,仅做记录
)…
解决方式
- 让AS取消掉对.9图片的安全检查。找到你app目录下的
build.gradle
文件,打开之后你可以在buildToolsVersion
属性之下添加取消安全检查的两行代码。
// 取消掉系统对.9图片的检查
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
- .9图片编译报错,那肯定说明你的.9图片制作不完善,你可以检查一下图片哪里没绘制好。你可以检查一下是否有重复绘制黑边,或者有哪条边没有绘制。这里注意:AS中要求.9图片的四条边都会绘制。