在运行时构建9个可绘制的补丁

时间:2013-05-12 16:15:09

标签: android graphics bytearray nine-patch android-drawable

我使用Brian Griffey提供的优秀要点(找到here)在Android 3.0+上成功构建了一个9patch drawable。

基本上我从网络加载原始(无补丁)图形文件,文件名包含我需要使用的上限,以便相应地缩放图像。然后,我将这些值与上面的类一起使用,并将图像作为背景应用于各种元素(例如TextViewImageButtonButtonViewGroup等)。

这完全正常,你可以在这里看到:

Android 3.0+ result

但是,在Android 2.3.x上运行相同的代码会产生结果:

Android 2.x result

我查看了Android中使用的源代码来解析9patch图像(herehere)但是没有找到使其正常工作的方法。我已经尝试过几乎所有可以投入的东西都无济于事。

对于记录,9patch由每个轴上的三列组成,一列固定,一个可伸缩,一个固定。

希望其他人以前解决过这个问题。

提前致谢。

编辑我只对在Android 2.3及更高版本上重复此行为感兴趣(我最初有2.x)。

编辑#2 此要点描述了exactly what I'm trying to do +来源图片:source image

编辑#3 图像的大小为22px / 58px(宽度/高度),插图为14/6/14/6(上/左/下/右)。

4 个答案:

答案 0 :(得分:16)

我更新代码后,它对我有用。我认为颜色大小因为某些原因而变得不开心(基于android源代码中的注释,每个补丁都有一个颜色提示,设置少于这个案例中的部分数量9似乎会导致问题)。我还没有测试你的图像。

public static NinePatch createFixedNinePatch(Resources res, Bitmap bitmap, int top, int left, int bottom, int right, String srcName){
    ByteBuffer buffer = getByteBufferFixed(top, left, bottom, right);
    NinePatch patch = new NinePatch(bitmap, buffer.array(), srcName);
    return patch;
}

public static ByteBuffer getByteBufferFixed(int top, int left, int bottom, int right) {
    //Docs check the NinePatchChunkFile
    ByteBuffer buffer = ByteBuffer.allocate(84).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)0x09);

    //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);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    return buffer;
}

答案 1 :(得分:5)

将我发现的所有内容整理到目前为止,并稍微磨练一下:

  • 在Android版本之间Res_png_9patch结构(字节块进入)之间似乎没有什么区别(请参阅http://code.metager.de/source/xref/android),所以这并不是&#39 ;看起来像是原因。

  • 关于九个补丁绘图的其他答案表明,每个区域(尤其是可伸缩的区域)应该至少为2x2像素(如果不是3x3),但在更小的区域之外更好。

  • 但是,分配一些字节块的方式看起来可以更新。尝试将第4个字节设置为9(我认为补丁的数量),在末尾添加7个NO_COLOR s并将其大小移动到56 +(7 x 4)= 84个字节

答案 2 :(得分:1)

看起来已经在SO上深入介绍了使用9个补丁 - Create a NinePatch/NinePatchDrawable in runtime

答案 3 :(得分:0)

不是问题的答案,而是一个有用的解决方法......

我总是发现在运行时使用9补丁文件是毛茸茸的。我已经成功地使用FrameLayouts并自动调整文本大小以实现我想要的效果。如果您的应用程序只是使用这个9补丁,而不是特别允许用户将其下载为图像(可以这么说是一个android 9-patch图像生成器),我会建议你研究一下。