@toc
前言
在实际开发中经常遇到一种情况: 用某张图片做控件背景,背景图片拉伸后导致显示变形。比如聊天窗口的气泡显示框,单纯的气泡图片不能自适应内容,导致文字或图片等超过框边界。又比如App的启动页放一张图片全屏显示,因为Android的机型屏幕尺寸、分辨率太多,导致这张图片在某些机型上显示图像变形。这时,9patch图片就派上用场了。9patch,又称".9"图片,与常规的图片相比,9patch格式的图片最大的特点就是能够最大程度的保证图片内容随着图片的拉伸不变形,这样就能适配各种屏幕分辨率的手机。
想来看一下实际对比效果。
<?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:id="@+id/message_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="@mipmap/bubble_bg"
android:layout_marginTop="8dp"
android:gravity="center_horizontal|end"
android:maxWidth="280dp"
android:paddingTop="18dp"
android:paddingBottom="8dp"
android:paddingLeft="14dp"
android:paddingRight="20dp"
android:textSize="18sp"
android:textColor="@color/font_grey_l"
android:text="的房价的看法佳都" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_gravity="right"
android:background="@mipmap/bubble_bg"
android:gravity="center_horizontal|end"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="14dp"
android:paddingRight="30dp">
<ImageView
android:id="@+id/message_image"
android:layout_width="150dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:src="@mipmap/demo"/>
</LinearLayout>
</LinearLayout>
这里有一个代表文本框的TextView和显示图片的布局都采用气泡图片做背景。代码设置了很多padding来保证内容不靠近四边框。
用图片查看器看下两张图片的不同:(右侧为.9图片)
左边黑线:表示图片的纵向拉伸的区域 顶部黑线:表示图片的横向拉伸的区域 默认情况下,图片整体会纵向和横向全部拉伸。设定了拉伸区域后,发生拉伸时,只有指定的区域会拉伸变化,其他区域是不变的。这样就保证了图片主要区域的显示不变形。 右边黑线:表示图片中的内容元素的纵向显示区域 底部黑线:表示图片中的内容元素的横向显示区域 默认情况下,图片中的内容元素会显示在背景图片内。但实际中,我们希望内容的显示是有要求的。比如上面的气泡背景,文字和图片应远离四周边框和尖角区域。这就是右边和底部标记黑线的作用。
好了,让我们进入主题,一步步来创建符合要求的点9图片吧。
创建编辑点9图片
Android Studio自带创建和编辑点9图片的功能。在需要创建点9的图片上右键:
Zoom:放大比例。默认100%。当编辑较小的图片或精确编辑图片时有用。 Patch scale:预览区域中横向、纵向以及整体拉伸效果的放大倍数。 Show content:勾选该选项,会展示内容的显示区域。用紫色表示。可以看到默认整个背景区域都会显示内容。
划重点来了: 将鼠标浮动在图片的左侧区域,会自动在图片顶和底显示两条横线。将鼠标放到其中的一根线上,光标编程上下箭头时,直接点击,会绘制整个边框;拖动鼠标,就可以绘制或取消拉伸区域。
接着,我们再来绘制内容显示区域。这里应避开不规则边框,尽可能在气泡中央位置显示。
示例
再看个类似的例子。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:gravity="center_horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="30dp"
android:gravity="center_horizontal"
android:paddingTop="15dp"
android:paddingBottom="30dp"
android:background="@mipmap/item_white_bg">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_personalcenteal"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="20sp"
android:textColor="@color/colorPrimaryDark"
android:text="功能模块"/>
</LinearLayout>
</LinearLayout>
显示如下:
当放大图片或文字尺寸后,可看到,图片已经显示了边框以外。
为防止图片或文字改变,导致图片或文字显示在背景图片以外,我们需要点9格式的背景图片。用上面提到的步骤来操作编辑,显示如下。
还有一个例子就是App的启动页。如下所示,当用这张图片作为启动页内容展示时,图片会铺满屏幕。
在高分辨率的手机上显示,普通的图片显示可能会内容失真,比如内容被拉伸变形等等。可以看到下图明显纵向被拉伸,导致圆形变成了椭圆形。
因为中央位置有图形和文字,所以拉伸区域应避开这块。我们选定了左右两边各指定一个横向拉伸区域来保证中央处不拉伸变形。左和顶部的拉伸区域绘制如下: