有时候我们想在其他地方加载 .9 path 图片,比如 assets 目录下,又或者从网上下载一个到sdcard 上,但是 bitmap.getNinePatchChunk() 总是 return null,而如果9path图片在drawable 文件下则可以。为什么会这样呢?是因为9path 图片有两种type,一种叫“source” 一种叫“compiled”. “source” 就是我们通过android sdk 工具制作好的9path 图片,“compiled” 就是打包apk 的时候aapt 会对9path图片进行编译。这就是我们为什么能使用drawable 下的9path图片,所以如果我们想在其他地方也正常使用9path 图片,那么我们就得事先对其进行compile,把编译好的在放在assets 目录或者其他地方。
编译命令 : aapt c -S nine_path_file_floder -C output_floder
// 加载9path并设置background
Bitmap bitmap =IconUtils.getBitmapFromFile("assets/easou_ecom_mads_bg_down.9.png");
final byte[] chunk = bitmap.getNinePatchChunk();
if (NinePatch.isNinePatchChunk(chunk)) {
bottomLayout.setBackgroundDrawable(new NinePatchDrawable(getContext().getResources(), bitmap, chunk, NinePatchChunk.deserialize(chunk).mPaddings, null));
}
//IconUtils.class
public static Bitmap getBitmapFromFile(String fileName) {
InputStream is = IconUtils.class.getClassLoader().getResourceAsStream(fileName);
return BitmapFactory.decodeStream(is);
}
//NinePatchChunk.class
public class NinePatchChunk {
public static final int NO_COLOR = 0x00000001;
public static final int TRANSPARENT_COLOR = 0x00000000;
public final Rect mPaddings = new Rect();
public int mDivX[];
public int mDivY[];
public int mColor[];
private static void readIntArray(final int[] data, final ByteBuffer buffer) {
for (int i = 0, n = data.length; i < n; ++i)
data[i] = buffer.getInt();
}
private static void checkDivCount(final int length) {
if (length == 0 || (length & 0x01) != 0)
throw new RuntimeException("invalid nine-patch: " + length);
}
public static NinePatchChunk deserialize(final byte[] data) {
final ByteBuffer byteBuffer =ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());
if (byteBuffer.get() == 0) return null; // is not serialized
final NinePatchChunk chunk = new NinePatchChunk();
chunk.mDivX = new int[byteBuffer.get()];
chunk.mDivY = new int[byteBuffer.get()];
chunk.mColor = new int[byteBuffer.get()];
checkDivCount(chunk.mDivX.length);
checkDivCount(chunk.mDivY.length);
// skip 8 bytes
byteBuffer.getInt();
byteBuffer.getInt();
chunk.mPaddings.left = byteBuffer.getInt();
chunk.mPaddings.right = byteBuffer.getInt();
chunk.mPaddings.top = byteBuffer.getInt();
chunk.mPaddings.bottom = byteBuffer.getInt();
// skip 4 bytes
byteBuffer.getInt();
readIntArray(chunk.mDivX, byteBuffer);
readIntArray(chunk.mDivY, byteBuffer);
readIntArray(chunk.mColor, byteBuffer);
return chunk;
}
}