13

我使用 Brian Griffey 提供的优秀要点(在此处找到)成功地在运行时在 Android 3.0+ 上构建了一个 9patch 可绘制对象。

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

正如您在此处看到的那样,这非常有效:

Android 3.0+ 结果

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

Android 2.x 结果

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

作为记录,9patch 在每个轴上由三列组成,一列固定,一列可拉伸,一列固定。

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

提前致谢。

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

编辑#2这个要点准确地描述了我正在尝试做的事情+ 源图像:源图像

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

4

4 回答 4

19

更新代码后它对我有用。我认为颜色大小出于某种原因使其不愉快(根据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;
}
于 2013-05-21T17:53:33.857 回答
5

把我到目前为止发现的所有东西放在一起,并稍微磨练一下:

  • Res_png_9patchandroid版本之间的结构(字节块进入)似乎没有区别(参见http://code.metager.de/source/xref/android),所以看起来不像原因。

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

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

于 2013-05-21T13:08:16.190 回答
1

看起来使用 9patches 已经在 SO 上进行了深入描述 -在运行时创建 NinePatch/NinePatchDrawable

于 2013-05-21T08:40:52.627 回答
0

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

我总是发现在运行时使用 9-patch 文件很麻烦。我已经成功地使用 FrameLayouts 和自动调整文本大小来实现我想要的效果。如果您的应用程序将仅使用此 9 补丁,而不是专门允许用户将其作为图像下载(可以说是一个 android 9 补丁图像生成器),我建议您研究一下。

于 2013-05-21T13:03:18.517 回答