NinePatchDrawable
ANinePatchDrawablegraphicisastretchablebitmapimage,
whichAndroidwillautomaticallyresizetoaccommodatethecontentsoftheViewinwhichyouhaveplaceditasthebackground.

AnexampleuseofaNinePatchisthebackgroundsusedbystandardAndroidbuttons—
buttonsmuststretchtoaccommodatestringsofvariouslengths.
ANinePatchdrawableisastandardPNGimagethatincl?sanextra1-pixel-wideborder.
Itmustbesavedwiththeextension.9.png,andsavedintotheres/drawable/directoryofyourproject.

Theborderisusedtodefinethestretchableandstaticareasoftheimage.
Youindicateastretchablesectionbydrawingone(ormore)1-pixel-wideblackline(s)intheleftandtoppartoftheborder.
(Youcanhaveasmanystretchablesectionsasyouwant.)Therelativesizeofthestretchablesectionsstaysthesame,
sothelargestsectionsalwaysremainthelargest.

Youcanalsodefineanoptionaldrawablesectionoftheimage(effectively,thepaddinglines)
bydrawingalineontherightandbottomlines.IfaViewobjectsetstheNinePatchasitsbackground
andthenspecifiestheView'stext,itwillstretchitselfsothatallthetextfitsinsideonly
theareadesignatedbytherightandbottomlines(ifincl?d).Ifthepaddinglinesarenotincl?d,
Androidusestheleftandtoplinestodefinethisdrawablearea.

Toclarifythedifferencebetweenthedifferentlines,
theleftandtoplinesdefinewhichpixelsoftheimageareallowedtobereplicatedinordertostretchtheimage.
ThebottomandrightlinesdefinetherelativeareawithintheimagethatthecontentsoftheViewareallowedtoliewithin.
ANinePatchDrawable相对于Bitmap Drawable主要有增加了两个属性。他主要定义了图片的两类可区域。
一类是一般的可扩展(放大)区域区域,他主要用来填充控件的空白区域。
另一类区域主要用于填充内容区域(比如对于button来说内容区域就是其文本区域)。

注意:
ThisNinePatchdefinesonestretchableareawiththeleft
andtoplinesandthedrawableareawiththebottomandrightlines.
Inthetopimage,thedottedgreylinesidentifytheregionsoftheimagethatwillbereplicatedinordertostretchtheimage.
ThepinkrectangleinthebottomimageidentifiestheregioninwhichthecontentsoftheViewareallowed.
Ifthecontentsdon'tfitinthisregion,thentheimagewillbestretchedsothattheydo.
使用Draw9-patch创建NinePatchDrawable形式的图(.9.png)

theDraw9-patchtoolallowsyoutoeasilycreateaNinePatchgraphicusingaWYSIWYGeditor.
Foranintrod tiontoNine-patchgraphicsandhowtheywork,
pleasereadthesectiononNine-patchintheNinepatchImagestopic.
Here'saquickguidetocreateaNine-patchgraphicusingtheDraw9-patchtool.You'llneedthePNGimagewithwhichyou'dliketocreateaNinePatch.

1.Fromaterminal,launchthedraw9patchapplicationfromyourSDK/toolsdirectory.
2.DragyourPNGimageintotheDraw9-patchwindow(orFile>Open9-patch...tolocatethefile).Yourworkspacewillnowopen.
Theleftpaneisyourdrawingarea,inwhichyoucaneditthelinesforthestretchablepatchesandcontentarea.
Therightpaneisthepreviewarea,whereyoucanpreviewyourgraphicwhenstretched.
3.Clickwithinthe1-pixelperimetertodrawthelinesthatdefinethestretchablepatchesand(optional)contentarea.
Right-click(orholdShiftandclick,onMac)toerasepreviouslydrawnlines.
可以在图片的框的四边上,按下鼠标左键并拖动可以画黑线,按下shift键的同时按鼠标左键并拖动可清除画的黑线。
A,左边那条黑色线代表图片垂直拉伸的区域,上边的那条黑色线代表水平拉伸区域。
他们的交集就区域代表就垂直拉伸和水平拉伸都可以进行的区域。
注意:我开始因为它是表达的只是他们的交集区域。
其实不是,它要表达的垂直拉伸和水平拉伸区域,不能只是交集区域。
因为如果只是交集区域的话,图片一放大,就不是长方形了。
B,右边的黑色线代表内容绘制的垂直区域,下边的黑色线代表内容绘制的水平区域
他们交集的区域就是内容所要绘制到的区域。
对于button来说就是文本的区域,这样就可以控制文本显示的区域。
如果
下边右边的黑线不是连续的,那它按最左端(上端)和最右端(下端)组成的线段来算内容区域。
注意:右边和下边的线是可选的,左边和上边的线不能省略

4.Whendone,selectFile>Save9-patch...
Yourimagewillbesavedwiththe.9.pngfilename.
Draw9-patch的使用,
NinePatchDrawable的使用和一般的Drawable一样,也是放在目录drawable下,
xml中引用如android:background="@drawable/test"的形式,其中"test"为文件名
参考资料:http://www.coolapk.com/docs/guide/developing/tools/draw9patch.html

NinePatch

TheNinePatchclasspermitsdrawingabitmapinninesections.
Thefourcornersareunscaled;thefouredgesarescaledinoneaxis,
andthemiddleisscaledinbothaxes.Normally,
themiddleistransparentsothatthepatchcanprovideaselectionaboutarectangle.
Essentially,itallowsthecreationofcustomgraphicsthatwillscalethewaythatyoudefine,
whencontentaddedwithintheimageexceedsthenormalboundsofthegraphic.
ForathoroughexplanationofaNinePatchimage,readthediscussioninthe2DGraphicsdocument.
TheDraw9-PatchtooloffersanextremelyhandywaytocreateyourNinePatchimages,usingaWYSIWYGgraphicseditor.
他可以让我们在运行时定制stretchable的区域和区域的填充方式。
它的构造函数只有一个。
Public Constructors
NinePatch( Bitmapbitmap, byte[] chunk, StringsrcName) Create a drawable projection from a bitmap to nine patches.
它的jni函数在 frameworks\base\core\jni\android\graphics\NinePatch.cpp
这里的byte[]chunk数据的格式一直不明白。
最后参看Android源码总算明白了。
chunk在jni(NinePatch.cpp)中主要用来构造Res_png_9patch这个结构体
chunk的至少有个sizeof(Res_png_9patch)大,即32个字节
Res_png_9patch的申明在

frameworks\base\incl?\utils\ResourceTypes.h
网上地址:http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=incl?/utils/ResourceTypes.h
Res_png_9patch的定义在frameworks\base\libs\utils\ResourceTypes.h中。
/** ******************************************************************** *  PNG Extensions * *  New private chunks that may be placed in PNG images. * *********************************************************************** *//** * This chunk specifies how to split an image into segments for * scaling. * * There are J horizontal and K vertical segments.  These segments divide * the image into J*K regions as follows (where J=4 and K=3): * *      F0   S0    F1     S1 *   +-----+----+------+-------+ * S2|  0  |  1 |  2   |   3   | *   +-----+----+------+-------+ *   |     |    |      |       | *   |     |    |      |       | * F2|  4  |  5 |  6   |   7   | *   |     |    |      |       | *   |     |    |      |       | *   +-----+----+------+-------+ * S3|  8  |  9 |  10  |   11  | *   +-----+----+------+-------+ * * Each horizontal and vertical segment is considered to by either * stretchable (marked by the Sx labels) or fixed (marked by the Fy * labels), in the horizontal or vertical axis, respectively. In the * above example, the first is horizontal segment (F0) is fixed, the * next is stretchable and then they continue to alternate. Note that * the segment list for each axis can begin or end with a stretchable * or fixed segment. * * The relative sizes of the stretchy segments indicates the relative * amount of stretchiness of the regions bordered by the segments.  For * example, regions 3, 7 and 11 above will take up more horizontal space * than regions 1, 5 and 9 since the horizontal segment associated with * the first set of regions is larger than the other set of regions.  The * ratios of the amount of horizontal (or vertical) space taken by any * two stretchable slices is exactly the ratio of their corresponding * segment lengths. * * xDivs and yDivs point to arrays of horizontal and vertical pixel * indices.  The first pair of Divs (in either array) indicate the * starting and ending points of the first stretchable segment in that * axis. The next pair specifies the next stretchable segment, etc. So * in the above example xDiv[0] and xDiv[1] specify the horizontal * coordinates for the regions labeled 1, 5 and 9.  xDiv[2] and * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that * the leftmost slices always start at x=0 and the rightmost slices * always end at the end of the image. So, for example, the regions 0, * 4 and 8 (which are fixed along the X axis) start at x value 0 and * go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at * xDiv[2]. * * The array pointed to by the colors field lists contains hints for * each of the regions.  They are ordered according left-to-right and * top-to-bottom as indicated above. For each segment that is a solid * color the array entry will contain that color value; otherwise it * will contain NO_COLOR.  Segments that are completely transparent * will always have the value TRANSPARENT_COLOR. * * The PNG chunk type is "npTc". */struct Res_png_9patch{    Res_png_9patch() : wasDeserialized(false), xDivs(NULL),                       yDivs(NULL), colors(NULL) { }    int8_t wasDeserialized;    int8_t numXDivs;    int8_t numYDivs;    int8_t numColors;    // These tell where the next section of a patch starts.    // For example, the first patch includes the pixels from    // 0 to xDivs[0]-1 and the second patch includes the pixels    // from xDivs[0] to xDivs[1]-1.    // Note: allocation/free of these pointers is left to the caller.    int32_t* xDivs;    int32_t* yDivs;    int32_t paddingLeft, paddingRight;    int32_t paddingTop, paddingBottom;    enum {        // The 9 patch segment is not a solid color.        NO_COLOR = 0x00000001,        // The 9 patch segment is completely transparent.        TRANSPARENT_COLOR = 0x00000000    };    // Note: allocation/free of this pointer is left to the caller.    uint32_t* colors;    // Convert data from device representation to PNG file representation.    void deviceToFile();    // Convert data from PNG file representation to device representation.    void fileToDevice();    // Serialize/Marshall the patch data into a newly malloc-ed block    void* serialize();    // Serialize/Marshall the patch data    void serialize(void* outData);    // Deserialize/Unmarshall the patch data    static Res_png_9patch* deserialize(const void* data);    // Compute the size of the serialized data structure    size_t serializedSize();};


注意2 :xDivs和yDivs用于确定可stretchable区域。
比如:
xDivs[0]和xDivs[1]确定一块可stretchable区域,
然后xDivs[2]和xDivs[3]又确定一块可stretchable区域
yDivs和xDivs一样。
注意2:colors指明了每个区域的填充颜色。
这里的区域并不区分非stretchable区域和stretchable区域
其中NO_COLOR=0x00000001,表示用图片的填充
TRANSPARENT_COLOR=0x00000000表示完全透明。
区域的顺序是从左到右,再从下到下。
下面详细说明byte[]chunk的和Res_png_9patch中变量的对应关系
第0个字节wasDeserialized备注
第1个字节numXDivsX方向可stretchable的区域数量
第2个字节numYDivsY方向可stretchable的区域数量
第3个字节numColorscolor数(每个区域对应一个color)
第4,5,6,7字节xDivsz指针在chunk中没意义
第8,9,10,11字节yDivsz指针在chunk中没意义
第12,13,14,15字节paddingLeft没发现有什么用
第16,17,18,19字节paddingRight没发现有什么用
第20,21,22,23字节paddingTop没发现有什么用
第24,25,26,27字节paddingBottom没发现有什么用
第28,29,30,31字节colors指针在chunk中没意义

从sizeof(Res_png_9patch)开始的数据(即第32个字节开始):
首先是xDivsz指针指向的内容,其大小为numXDivs个int32_t
然后是yDivs指针指向的内容,其大小为numYDivs个int32_t
最后是colors指针指向的内容,其大小为numColors个int32_t(ARGB格式)
注意:对于int32_t这种多字节的类型是高字节在内存的高位
示例1
代码1

BitmapDrawablebitmapDrawable=(BitmapDrawable)context.getResources().getDrawable(R.drawable.icon);
Bitmapbitmap=bitmapDrawable.getBitmap();
intwidth=bitmap.getWidth();
System.out.println("width:"+width);
bytenumXDivs=4;
bytenumYDivs=4;
bytenumColors=numXDivs;
intpaddingLeft=10;
intoffset=0;
numColors=(byte)((numColors+1)*(numYDivs+1));

int size=32+(numXDivs+numYDivs+numColors)*4;
bytechunk[]=newbyte[size];
chunk[0]=0;
chunk[1]=numXDivs;
chunk[2]=numYDivs;
chunk[3]=numColors;
bytepVal=0;
chunk[4]=pVal;
chunk[5]=pVal;
chunk[6]=pVal;
chunk[7]=pVal;

chunk[8]=pVal;
chunk[9]=pVal;
chunk[10]=pVal;
chunk[11]=pVal;
offset=12;
putInt(chunk,offset,paddingLeft);
offset+=4;
offset=32;
putInt(chunk,offset,10);
offset+=4;
putInt(chunk,offset,30);
offset+=4;
putInt(chunk,offset,40);
offset+=4;
putInt(chunk,offset,width);
offset+=4;

putInt(chunk,offset,11);
offset+=4;
putInt(chunk,offset,18);
offset+=4;
putInt(chunk,offset,30);
offset+=4;
putInt(chunk,offset,56);
offset+=4;
intcolor=0x00000F;
intcolor2=0xFFFFF0;
intcolorInc=(color2-color)/numColors;
for (inti=0;i<numColors;i++)
{
putInt(chunk,offset,0x2F000000|color);
offset+=4;
color+=colorInc;
}
img9Patch=newNinePatch(bitmap,chunk,null);
代码2
staticvoid putInt (bytearray[],intoffset,intval)
{
array[offset]=(byte)(val&0xFF);
val=val>>8;
array[offset+1]=(byte)(val&0xFF);
val=val>>8;
array[offset+2]=(byte)(val&0xFF);
val=val>>8;
array[offset+3]=(byte)(val&0xFF);
}

代码3 :
RectFrect=newRectF(0,0,Game.width,Game.height);
img9Patch.draw(canvas,rect);

注意1:rect是要把img9Patch画到的区域。

更多相关文章

  1. android(11)_文件操作读取模式
  2. Android中给Spinner或ListView添加数据
  3. android Activity 清空焦点
  4. Android(安卓)textview获取选中的内容
  5. android 图片处理大全
  6. android2.2更新为android2.3
  7. android 自定义viewR.styleable找不到或者是报错!
  8. android字符串处理(Mms模块短信内容解析)
  9. android 之 新浪微博

随机推荐

  1. Android(安卓)短信发送器的实现
  2. [Android(安卓)Studio]蓝牙通信(Fragment
  3. Android(安卓)Studio相关配置Mac版
  4. [Android] Opengl ES 机型适配 bug 汇总
  5. Android(安卓)Studio 安装完成后,遇到的问
  6. 更改系统时区
  7. Android(安卓)Binder 驱动 - 内核驱动层
  8. Android(安卓)ADB命令详解
  9. Android(安卓)Studio 单元测试之简单版
  10. 关于Activity的少许细节