工作和測試 - 運行時NINEPATCH CREATION
這是我實現的Android Ninepatch生成器,您可以通過提供任何位圖
public class NinePatchBuilder {
int width,height;
Bitmap bitmap;
Resources resources;
private ArrayList<Integer> xRegions=new ArrayList<Integer>();
private ArrayList<Integer> yRegions=new ArrayList<Integer>();
public NinePatchBuilder(Resources resources,Bitmap bitmap){
width=bitmap.getWidth();
height=bitmap.getHeight();
this.bitmap=bitmap;
this.resources=resources;
}
public NinePatchBuilder(int width, int height){
this.width=width;
this.height=height;
}
public NinePatchBuilder addXRegion(int x, int width){
xRegions.add(x);
xRegions.add(x+width);
return this;
}
public NinePatchBuilder addXRegionPoints(int x1, int x2){
xRegions.add(x1);
xRegions.add(x2);
return this;
}
public NinePatchBuilder addXRegion(float xPercent, float widthPercent){
int xtmp=(int)(xPercent*this.width);
xRegions.add(xtmp);
xRegions.add(xtmp+(int)(widthPercent*this.width));
return this;
}
public NinePatchBuilder addXRegionPoints(float x1Percent, float x2Percent){
xRegions.add((int)(x1Percent*this.width));
xRegions.add((int)(x2Percent*this.width));
return this;
}
public NinePatchBuilder addXCenteredRegion(int width){
int x=(int)((this.width-width)/2);
xRegions.add(x);
xRegions.add(x+width);
return this;
}
public NinePatchBuilder addXCenteredRegion(float widthPercent){
int width=(int)(widthPercent*this.width);
int x=(int)((this.width-width)/2);
xRegions.add(x);
xRegions.add(x+width);
return this;
}
public NinePatchBuilder addYRegion(int y, int height){
yRegions.add(y);
yRegions.add(y+height);
return this;
}
public NinePatchBuilder addYRegionPoints(int y1, int y2){
yRegions.add(y1);
yRegions.add(y2);
return this;
}
public NinePatchBuilder addYRegion(float yPercent, float heightPercent){
int ytmp=(int)(yPercent*this.height);
yRegions.add(ytmp);
yRegions.add(ytmp+(int)(heightPercent*this.height));
return this;
}
public NinePatchBuilder addYRegionPoints(float y1Percent, float y2Percent){
yRegions.add((int)(y1Percent*this.height));
yRegions.add((int)(y2Percent*this.height));
return this;
}
public NinePatchBuilder addYCenteredRegion(int height){
int y=(int)((this.height-height)/2);
yRegions.add(y);
yRegions.add(y+height);
return this;
}
public NinePatchBuilder addYCenteredRegion(float heightPercent){
int height=(int)(heightPercent*this.height);
int y=(int)((this.height-height)/2);
yRegions.add(y);
yRegions.add(y+height);
return this;
}
public byte[] buildChunk(){
if(xRegions.size()==0){
xRegions.add(0);
xRegions.add(width);
}
if(yRegions.size()==0){
yRegions.add(0);
yRegions.add(height);
}
/* example code from a anwser above
// The 9 patch segment is not a solid color.
private static final int NO_COLOR = 0x00000001;
ByteBuffer buffer = ByteBuffer.allocate(56).order(ByteOrder.nativeOrder());
//was translated
buffer.put((byte)0x01);
//divx size
buffer.put((byte)0x02);
//divy size
buffer.put((byte)0x02);
//color size
buffer.put((byte)0x02);
//skip
buffer.putInt(0);
buffer.putInt(0);
//padding
buffer.putInt(0);
buffer.putInt(0);
buffer.putInt(0);
buffer.putInt(0);
//skip 4 bytes
buffer.putInt(0);
buffer.putInt(left);
buffer.putInt(right);
buffer.putInt(top);
buffer.putInt(bottom);
buffer.putInt(NO_COLOR);
buffer.putInt(NO_COLOR);
return buffer;*/
int NO_COLOR = 1;//0x00000001;
int COLOR_SIZE=9;//could change, may be 2 or 6 or 15 - but has no effect on output
int arraySize=1+2+4+1+xRegions.size()+yRegions.size()+COLOR_SIZE;
ByteBuffer byteBuffer=ByteBuffer.allocate(arraySize * 4).order(ByteOrder.nativeOrder());
byteBuffer.put((byte) 1);//was translated
byteBuffer.put((byte) xRegions.size());//divisions x
byteBuffer.put((byte) yRegions.size());//divisions y
byteBuffer.put((byte) COLOR_SIZE);//color size
//skip
byteBuffer.putInt(0);
byteBuffer.putInt(0);
//padding -- always 0 -- left right top bottom
byteBuffer.putInt(0);
byteBuffer.putInt(0);
byteBuffer.putInt(0);
byteBuffer.putInt(0);
//skip
byteBuffer.putInt(0);
for(int rx:xRegions)
byteBuffer.putInt(rx); // regions left right left right ...
for(int ry:yRegions)
byteBuffer.putInt(ry);// regions top bottom top bottom ...
for(int i=0;i<COLOR_SIZE;i++)
byteBuffer.putInt(NO_COLOR);
return byteBuffer.array();
}
public NinePatch buildNinePatch(){
byte[] chunk=buildChunk();
if(bitmap!=null)
return new NinePatch(bitmap,chunk,null);
return null;
}
public NinePatchDrawable build(){
NinePatch ninePatch=buildNinePatch();
if(ninePatch!=null)
return new NinePatchDrawable(resources, ninePatch);
return null;
}
}
創建通過這個類和代碼示例下方運行NinePatches
現在我們可以使用ninepatch生成器創建ninePatch或NinePatchDrawable或創建ninePatch塊。
例子:
NinePatchBuilder builder=new NinePatchBuilder(getResources(), bitmap);
NinePatchDrawable drawable=builder.addXCenteredRegion(2).addYCenteredRegion(2).build();
//or add multiple patches
NinePatchBuilder builder=new NinePatchBuilder(getResources(), bitmap);
builder.addXRegion(30,2).addXRegion(50,1).addYRegion(20,4);
byte[] chunk=builder.buildChunk();
NinePatch ninepatch=builder.buildNinePatch();
NinePatchDrawable drawable=builder.build();
//Here if you don't want ninepatch and only want chunk use
NinePatchBuilder builder=new NinePatchBuilder(width, height);
byte[] chunk=builder.addXCenteredRegion(1).addYCenteredRegion(1).buildChunk();
只要複製粘貼到一個java文件NinePatchBuilder類代碼,並使用實例您的應用程序在運行時動態創建NinePatch,的任何決議。
正如mreichelt所說,文檔說_「返回一個可選的私有數據數組,由UI系統用於某些位圖,不打算由應用程序調用。所以這種方法不能使用。不管怎麼說,還是要謝謝你! – jacob11