1. 程式人生 > 實用技巧 >NinePatch圖(9-Patch圖,.9圖)

NinePatch圖(9-Patch圖,.9圖)

NinePatch圖(9-Patch圖,.9圖)

https://www.uisdc.com/about-draw9patch

一. 什麼是點九圖

點九圖其實就是安卓系統中特有的一種圖片格式,為了讓大家更好的記住,我們只要知道,字尾名是「.9.png」的圖片,就是點九圖。

二. 點九圖的作用是什麼

每個事物都有其存在的價值,所以先弄清楚點九圖能為我們解決什麼問題,這樣後面理解起來就會容易很多。

其實點九圖的用處就是幫助我們拉伸切圖的,比如這個切圖:

如果它需要縱向拉伸,直接拉會變成下面這個樣子:

而用了點九圖就可以讓切圖區域性拉伸,而不是整體拉伸,這樣就可以把容易變形的地方保護起來:

是不是拉伸的很完美!有黑線不用怕,那只是告訴安卓系統:嘿,大兄弟,這是張點九圖,特殊對待一下!

這有能讓你快速製作點九圖的小教程 →《你知道Android裡的“點九”嗎?》

三. 點九圖的原理

點九圖最大的原則就是四個邊必須各有一條純黑的線(或一畫素的點),如下圖:

如果四條線少任何一條,或者線不是純黑的(#000000),安卓系統就不認你!

其中這四條線,左上兩條線掌管可拉伸區域,右下兩條線掌管內容顯示區:

先說左上兩條線,因為兩條線原理是一樣的,所以我們單獨拿左邊這條線來舉例吧,當我們沒有左邊那條黑線時,縱向拉伸是這樣的:

圓角是不是變形了,如果左邊加一條黑線,就相當於把原來的圖形分為三個部分:

當再次縱向拉伸的時候,只有標記了黑線的部分可以被拉伸,而上下兩部分是完好無損的,想象一下,無論你拉伸到多高,是不是都不會變形了:

當然,你左邊畫一個點也可以起到相同的效果:

左邊這條線是控制縱向拉伸的,所以上面那條黑線就是控制橫向拉伸的,原理是一樣的!

接下來我們來說右下兩條線,是控制內容區域的,單獨拿右邊那條線來舉例,如果沒有右邊那條黑線,在這個切圖上輸入內容,比如文字,是沒有限制的,內容會撐滿整個背景圖:

當有了右邊那條黑線後,切圖相當於在縱向上又被分開了:

而這次是右邊有黑線哦,別忘了右邊的黑線是控制顯示區域的,所以只有帶黑線的部分才可以顯示內容。

當然,文字不會這樣被切斷一半顯示的,這裡只是方便大家觀看哪裡可以顯示內容!

同樣的原理,當我下面也畫一條線後,橫向上也是隻有帶黑線的部分可以顯示內容(紅線是輔助示意的哈):

這就是點九的基本原理了!

四. 總結

最後總結幾個要點:

  • 點九切圖四周必須要有四條一畫素純黑的線或點。
  • 左上兩條線控制拉伸區,右下兩條線控制內容區。
  • 輸出的圖片字尾必須是「.9.png」。

至於用外掛還是自己手動切點九圖,看自己習慣吧,我一般都是自己畫,比較放心一點。

==================

說明

本文部分技術相關內容主要供Android開發者閱讀;大部分內容設計人員也可以學習。

谷歌官方文件https://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch

本文配套工程原始碼https://github.com/jzj1993/NinePatch

基本介紹

NinePatch圖(9-Patch圖,.9圖)是一種可拉伸的圖片(stretchable bitmap image)。

  1. NinePatch圖片的檔名應為xxx.9.png

  2. 在png圖片基礎上,上下左右四個方向各留出一個畫素的邊緣,使用黑色畫素點定義拉伸和內容區域,其他畫素點應該是白色或透明

  3. 左、上兩邊的黑色畫素點,分別表示水平、垂直方向的縮放區域(stretchable area)。縮放區域可以有多段,縮放時會按比例進行縮放。

    You can have as many stretchable sections as you want: their relative size stays the same, so the largest sections always remain the largest.

  4. 右、下兩邊的黑色畫素點,分別表示水平、垂直方向的內容區域(padding lines)。內容區域相當於設定Padding,應該是一段連續區域,且9-Patch圖的內容區域是可選的。

  5. 如果NinePatch圖沒有定義內容區域,則使用左、上定義的縮放區域作為內容區域

    If the padding lines are not included, Android uses the left and top lines to define this drawable area.
    如圖,實際測試發現,內容區域為白框中的區域

  6. 程式碼開發相關

    • 可以通過程式碼設定Padding,覆蓋9-Patch圖的內容區域。
    • 當文字等內容小於內容區域時,可通過gravity屬性指定內容的對齊方式。
  • NinePatch圖可以設定給任意View的background屬性。如果要設定給ImageView的src屬性,則需要設定成fitXY模式。

以一個文字框(TextView)為例:

  • 文字會顯示到矩形內容區域(PaddingBox),顯示不下就會進行拉伸,文字比內容區域小時不會壓縮。
  • 拉伸時,水平和垂直方向,會分別按照定義的一個或多個拉伸區域,按比例均勻拉伸。

基本示意圖如下:

典型示例

下面有幾個示例,NinePatch切圖,以及實際顯示效果如下。

  1. 常規文字氣泡

  2. 橢圓氣泡。將整個區域設定成拉伸區域

  3. 半圓氣泡。如果希望文字較高時仍然是半圓,直接使用程式碼實現會更容易。

  4. 多個拉伸區域。頂部的箭頭左邊有10畫素拉伸控制點,右邊有5畫素,會按2:1縮放。

    需要等比拉伸的情況,拉伸畫素最好多一些,例如10個:5個,儘量避免只有一兩個畫素,否則在低版本Android裝置上可能會出現較大誤差。

  5. 沒有定義內容區域。右下兩側邊框是全透明的

  6. 最終顯示效果

  7. 注:例4中的2:1,指的是拉伸區域,即下圖中的紅框區域為2:1

減小切圖尺寸

由於9-patch圖能縮放,因此可以利用這個特點減小切圖尺寸,從而減少APK檔案大小,減小記憶體、CPU消耗,提高APP效能。例如下面的左圖,可以壓縮成右圖。

NinePatch圖與程式碼實現形狀

一些常見的形狀可以直接使用程式碼實現(ShapeDrawable、GradientDrawable),實現容易,而不需要用切圖,且效能更好、清晰度更高。例如直線、矩形、圓形、橢圓形、圓角矩形等。

Draw9Patch工具

Draw9Patch是Android開發包中提供的NinePatch檢視和調整工具,檔案位於<android-sdk>/tools/lib/draw9patch.jar,安裝Java環境後可雙擊執行。

Draw9Patch工具可在此下載:https://github.com/jzj1993/NinePatch/blob/master/draw9patch.jar
Java環境可在Java官網下載安裝:https://www.java.com

在Draw9Patch工具中

  1. 單擊邊緣可以新增黑點,Shift+單擊可以刪掉黑點,拖動可以調整黑點長度。
  2. 勾選Show Content等選項可以檢視內容、縮放等區域
  3. 右側可預覽不同拉伸情況下的效果,拖動Patch scale可以調整預覽的拉伸比例

Android Studio的檔案預覽中也集成了Draw9Patch

Draw9Patch工具官方文件https://developer.android.com/studio/write/draw9patch.html

Android Studio的快取問題

在較高版本的Android Studio中,為了提高XML預覽效能,會建立一些快取,導致新的圖片替換後並不一定能重新整理顯示,因此可以嘗試使用File-Invalidate Caches/Restart…重啟並重新整理快取。

================== End