Android 9patch 实例详细介绍

本文深入解析9妹图(*.9.png)在安卓开发中的应用,介绍如何通过draw9patch工具制作适应不同尺寸需求的背景图,确保图片在缩放过程中不失真,并保持良好的用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网上看了许多 讲解 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不美观把责任丢给美工;美工说图片的缩放处理是你们程序的事,不管我的事。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值