我需要帮助NinePatchDrawable:
我的应用程序可以从网络下载主题.
几乎所有的事情都可以正常工作,除了9-Patch PNG.
final Bitmap bubble = getFromTheme("bubble"); if (bubble == null) return null; final byte[] chunk = bubble.getNinePatchChunk(); if (!NinePatch.isNinePatchChunk(chunk)) return null; NinePatchDrawable d = new NinePatchDrawable(getResources(),bubble,chunk,new Rect(),null); v.setBackgroundDrawable(d); d = null; System.gc();
getFromTheme()从SD卡加载Bitmap. 9-Patch PNG已经被编译,这意味着它们包含了所需的块.
我将Bitmap转换为NinePatchDrawable对象的方式似乎是有效的,因为图像是可拉伸的,并且我绘制它.
唯一不起作用的是填充.我已经尝试将填充设置为这样的视图:
final Rect rect = new Rect(); // or just use the new Rect() set d.getPadding(rect); // in the constructor v.setPadding(rect.left,rect.top,rect.right,rect.bottom);
d.getPadding(rect)应该从块中填充变量rect,不应该吗?但它没有.
结果:TextView(v)不显示9-Patch图像的内容区域中的文本.每个坐标中的paddings设置为0.
谢谢阅读.
解决方法
最后,我做到了Android没有正确解释块数据.可能有bug所以你必须自己反序列化块以获取填充数据.
开始了:
package com.dragonwork.example; import android.graphics.Rect; import java.nio.ByteBuffer; import java.nio.ByteOrder; 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; } }
使用上面的类如下:
final byte[] chunk = bitmap.getNinePatchChunk(); if (NinePatch.isNinePatchChunk(chunk)) { textView.setBackgroundDrawable(new NinePatchDrawable(getResources(),bitmap,NinePatchChunk.deserialize(chunk).mPaddings,null)); }
它会工作完美!