NinePatch 图像是一种特殊的 PNG 图像,它允许 Android 系统根据内容自动调整图像大小,而不会产生任何失真和拉伸。这使开发人员可以创建可缩放的 UI 元素,如按钮、进度条和背景图像,而无需为不同的屏幕尺寸准备多个资源集。
创建 NinePatch 图像
Draw 9-patch 是 Android Studio 中用于创建和编辑 NinePatch 图像的工具。它允许开发人员直观地沿着边界绘制黑色像素线,并预览图像在不同尺寸下的外观。除了 Android Studio 自带的工具外,还有许多在线资源和应用程序可用于制作 NinePatch 图像,例如 9 Patch Editor。
NinePatch 图像的用法
在 Android 应用程序中使用 NinePatch 图像非常简单:您将它们添加到项目的 res/drawable 文件夹中,然后在 XML 布局文件中使用 android:background 引用它们。例如:
<Button android:id="@+id/tiny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:text="Tiny"
android:textSize="8sp"
android:background="@drawable/my_button_background"/>
<Button android:id="@+id/big"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:text="Biiiiiiig text!"
android:textSize="30sp"
android:background="@drawable/my_button_background"/>
请注意,layout_width 和 layout_height 应为 wrap_content,以整齐地显示带有文本的按钮。
下图显示了通过 XML 和 NinePatch 图像渲染的两个按钮。如上图所示,观察按钮的宽度和高度如何随文本变化,而背景图像被拉伸以适应屏幕。

NinePatch 的应用场景
-
按钮背景: 这是 Drawables 最常见的应用场景。由于不同按钮的文本长度可能不同,NinePatch 可确保背景图像完全覆盖且不会超出边界,也不会因内部文本位置而变形。例如,如果我们有一个圆角按钮背景,我们将使用 NinePatch,无论按钮文本的长度如何,圆角都将保持不变。
-
进度条背景: 它会随着进度条在固定单位距离上拉伸背景图像,其中单位距离是不同的,并且会随着从一个系统到另一个系统的加载而变化。NinePatch 将确保背景图像的样式在拉伸时不会失真。
-
列表项的背景: 在列表视图中,这些列表项的背景实际上需要根据放入视图中的内容长度而有所不同。NinePatch 可确保背景图像在不失真的情况下完美拉伸。
-
对话框框架背景: 在这种情况下,对话框的大小会随内容变化。NinePatch 可确保背景图像始终以相同的样式拉伸。
-
可缩放分隔符: 通过 NinePatch,用户可以设计水平或垂直的可拉伸分隔符,以适应多种屏幕尺寸和布局的适应性。
-
用户定义的形状背景: NinePatch 可构建各种用户定义的形状背景,例如圆角、阴影等,在拉伸时这些特殊效果不会发生变化。
NinePatch 的优点
- 可伸缩性: 这是 NinePatch 最大的优势。根据内容自动调整大小,从而无需为不同的屏幕尺寸和内容长度维护多个资源集。
- 避免失真: 对可拉伸区域的坐标控制可防止图像拉伸。在大多数情况下,保留了清晰度和美观性。
- 提高效率: 减少资源文件,从而提高开发效率。
- 灵活的排列: 它可以轻松创建不同形状和大小的 UI 元素,以适应各种布局要求。
NinePatch 的工作原理
NinePatch 图像的标志是完全狭窄的像素边框。该边框定义了图像内容的可伸缩性和区域。在边缘绘制黑色像素线表示哪些部分在周边拉伸,哪些部分垂直拉伸,哪些部分水平拉伸。

特别是,1 像素边框分为四个部分:
1. 左边框(垂直黑色像素线):
-
功能: 控制图像的垂直拉伸。左边框上的垂直黑色像素线定义了图像的哪些区域可以垂直拉伸。
-
例如:
-
无黑色像素线: 图像的高度是固定的;因此,它不具备垂直拉伸的能力。如果尝试将其放入比图像本身更高的容器中,它将保持原样,并且可能存在空白区域或被裁剪。
-
一条黑色像素线: 图像可以垂直拉伸,但仅限于黑色像素线指定的区域。例如,如果黑色像素线位于左边框的中间,则表示上半部分和下半部分不会改变,仅允许在中间部分进行垂直拉伸。
-
多条黑色像素线: 可以定义多个垂直拉伸区域。例如,左边框会有两条黑色像素线,将图像分成三个部分,中间部分可拉伸,顶部和底部部分保持不变。
-
2. 上边框:(水平黑色像素线):
-
功能: 控制图像的水平拉伸。顶部边框上的水平黑色像素线定义了图像在水平维度上的可拉伸部分。
-
例如:
-
无黑色像素线: 图像的宽度是固定的,并且不会水平拉伸。与左边框上没有黑色像素线的情况类似,图像将保持不变,但可能存在空白区域或被裁剪。
-
一条黑色像素线: 图像可以水平拉伸,但也仅限于黑色像素线指定的区域。例如,如果黑色像素线位于上边界的中间,则图像的左半部分不会改变,右半部分也不会改变,仅允许在中间进行一些拉伸。
-
多条黑色像素线: 它定义了多个横向可拉伸区域。就像左边框有多个水平黑色像素线的情况一样,它将图像分成多个部分,并且任何标记的部分都可以水平拉伸。
-
3. 右边框(垂直黑色像素线):
-
功能: 定义内容区域的右边距。右边距上的垂直黑色像素线指示图像内容区域的右边界。在拉伸期间,内容区域的右侧将保持在此边界上。
-
示例:
-
无黑色像素线: 内容区域一直延伸到图像的右边距,当内容拉伸时不会弯曲,从而使图像内容延伸到右边缘。
-
一条黑色像素线: 内容区域的右边缘由黑色像素线的位置确定。拉伸时,内容区域的右侧将保持在黑色像素线的位置,而右侧的空间将被拉伸。
-
4. 底边框(水平黑色像素线):
-
功能: 定义内容限定区域的下边距。底部的水平黑色像素线定义了图像内容区域的下边界的结束位置。拉伸时,内容区域的底部将保持在该边界。
-
示例:
-
无黑色像素线:内容区域延伸到图像的底部边缘。拉伸时,整个图像内容将拉伸到底部边缘。
-
一条黑色像素线:内容区域的下边界来自黑色像素线的位置。拉伸时,内容区域的底部将保持在黑色像素线的水平,并且下面的空白将被拉伸。
-
通过在这些四个边框上巧妙地使用黑色像素线,程序员可以精确地控制 NinePatch 图像在不同尺寸下的显示方式,同时确保在不失真或丢失内容区域的情况下进行显示。请记住,这些像素线是可拉伸区域与内容区域的定义边界,而不是图像的实际边界。没有黑色像素线的部分是固定大小的组件。
注意事项
- NinePatch 图像应以
.9.png结尾的文件名保存。 - 可拉伸区域的最小尺寸为 2x2 像素,以使图像在缩放时不会消失。
- 可拉伸区域边缘处的额外安全空间可以消除缩放时发生的颜色变化。
- 请务必非常仔细地检查图像的可拉伸区域和内容区域,以确保图像在不同尺寸下正确显示。
- 不要过度使用 NinePatch 图像,尤其是在动画界面或频繁更改的界面中,因为它们会降低性能。
总结
NinePatch 图像是提高 UI 设计效率和改善 Android 应用程序用户体验的最强大工具。但是,这并不意味着开发人员不必权衡其优点和局限性,因为图像类型的选择取决于需求。例如,即使 NinePatch 图像是可缩放背景或需要接受不同长度文本的 UI 元素的正确选择,普通的 PNG 图像对于静态背景图像也完全足够 - 它们的简单性是关键。在使用 NinePatch 时,必须在设计和测试中格外小心,以确保它在各种设备和屏幕尺寸上都能完美运行。