网上看了许多 讲解 9妹图的 博客,感觉有些地方跟自己的理解有点出入,特地拿来研究一翻,并记录心得。
说点题外话, 自我勉励。作为一个安卓开发的Coder ,应该努力做到让自己的应用更容易被更多的人接受,这种精益求精的态度是你在这个圈子里混的名片。好了,不扯远了,再扯就扯到 “为兴趣编程还是为钱编程” 的哲学问题了。
1、问题所在:背景图缩放导致的图片失真
先来看看下面这张截图
图片中一共有 7 个 大小不同 Button 按钮,每个 Button 的 背景 都是 右边这张图片:,当Button的大小变化时,会自动均匀
缩放 背景图片,这就导致 图片 细节轮廓上变得模糊,影响用户体验。一个好的UI设计师需要对每一张图进行精确到像素级 的 制图,以带给用户最佳的体验。
2、其它平台上的解决方案
这种问题在 Web 开发上经常 会碰到,传统的解决方案就是在 网页中 使用 table表格 写三行类似九宫格的布局 针对不同部位写不同的代码 ,四个角的图片不会改变,只需要拉伸上、下、左、右四个边的图片, 但是这样做无疑加大了开发的工作量。
3、安卓平台的解决方案: *.9.png
安卓平台提供了很好的解决方案 : *.9.png , 同时在安卓SDK中 Android / tools / 文件夹下 自带了 draw9patch.bat 工具, 用于制作 *.9.png
工具运行的效果图
左边是 需要操作的素材, 可以通过下方的 Zoom 工具 缩放 原图大小, 以更方便进行 像素级 的操作;
右边三个图自上至下分别是 仅竖向缩放、仅横向缩放、横竖同时缩放 之后的 效果图预览,
4、上边 和 左边 一像素的 意义: 控制拉伸
*.9.PNG是标准的PNG格式,只是在最外面一圈额外增加1px的边框,这个1px的边框就是用来定义图片中可扩展的和静态不变的区域。left 和 top 边框中交叉部分是可拉伸部分,未选中部分是静态区域部分。当图片需要拉伸来适应View的大小时,只会拉伸 left 和 top 上标识 为 黑色的部分,不会拉伸未标识为黑色的部分。(至于拉伸的规则,可以参考 计算机图形学,如何线性渐变等)
5、右边 和 下边 一像素 的 意义: 控制内容显示区域
9patch 图 的 左边和上边 很好理解, 但是右边和下边是如何控制内容显示区域呢? 网上许多文章对 右边和下边 的 讲解不是很透彻,大多没有经过 实践考验,人云亦云。 讲到控制内容显示的时候 大多 一笔带过。
其实,如果只是 希望图片 自动 拉伸相应的区域 来 适应 Android 不同的 View , 只需要 使用 左和上 。 例如, 只有一个 Button 按钮有 背景图片, 而且此Button上没有button.setText() , 就是说按钮上没有 “确定”、“取消”之类的文字, 这个时候是不需要 右、下 边 的
但是,如果要在 Button 上设置 如 “点击保存 ”、“选择支付类型” …… 的文字时,明显看到, Button 上的文字明显 挤压 在 一起, 这里你也许会 想到 使用 button.setPadding() 方法 来解决 文字 和 按钮 内边距 的 问题, 但是看上面这张图的 下边上 有一个 凸起 的 箭头, 怎么估算他的 setBottom 值呢? 而且, 不同像素密度的手机,这个值还有可能是不同。 这时 , 右、下 边线 就起到作用了
右边 和 下边 黑色 线段 的 起点 和 终点 位置处 分别 对应 两条 水平直线 和 两条 竖直直线 , 将 图片 分成 9 块区域, 其中 5号区域是用来 盛放 “确定”、“取消” 文字内容的。
聪明的朋友会问,为什么当图片拉伸变大后,内容显示区域也变大了,不是说被这四条包裹的区域才是内容区吗?
注意: 静止不变的 部分是 12346789 这 8 个区域 来 控制 内容区的, 比如 当 竖直拉伸前后, 线1和上边的距离 是不会改变的,换句话说:是通过线1与上边的距离来决定竖直拉伸后 内容区的上边与图片的最上边的距离。 是向外发散来控制内容区的大小,而不是说 四条 包围的地方 就是 内容区。因此当图片拉伸后,内容区也跟着扩大,但是内容区距离图片的边距是不会改的,最终起到了 setPadding的作用,而与代码无关、设备像素密度无关,又是通过图片本身来解决前面提到的setBottom的值不能确定多少的问题,
做到一次设计,随处利用。
这才是这篇文章要表达的重点。
<Button
android:id="@+id/btn2"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/ballon2"
android:text="-12345612333333333333372133333333333333333332222222222222222"/>
例如: 下面 第一张 带 右、下 边 的 .9 图 ,生成 的 Button 的 最终 效果 如下右图所示:
事不目见耳闻,而臆断其有无,可乎?郦元之所见闻,殆与余同,而言之不详;士大夫终不肯以小舟夜泊绝壁之下,故莫能知;而渔工水师虽知而不能言。此世所以不传也。而陋者乃以斧斤考击而求之,自以为得其实。余是以记之,盖叹郦元之简,而笑李渤之陋也。
程序员多以为这是美工的任务,不管自己的事,APP不美观把责任丢给美工;美工说图片的缩放处理是你们程序的事,不管我的事。