首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android:编译9补丁文件以在可绘制文件夹之外使用?

Android:编译9补丁文件以在可绘制文件夹之外使用?
EN

Stack Overflow用户
提问于 2011-06-29 01:14:44
回答 2查看 4.4K关注 0票数 5

我需要从drawable文件夹之外加载9-patch文件。例如,这是为了让我的应用程序可以从服务器下载新的皮肤。我发现存储在可绘制文件夹中的9补丁图像是在制作.apk时编译的。从assets文件夹读取的完全相同的文件没有9-patch块。因此,生成.apk的操作是在可绘制文件夹中编译源9-patch文件,而不是在资产目录中。

我如何自己编译一个包含9个补丁的文件,以便可以将其安装在资源目录中?有没有一个(批处理)工具可以将源代码转换为带有9-patch块的编译版本?我真的非常希望不必使用Eclipse来构建一个.apk,然后在可能的情况下将其解压到编译后的9-patch文件中。

现在,我只希望能够读取资源目录(例如,每个皮肤都有一个子目录),以保持简单。下一步是编译源映像以添加到9-patch块中。在那之后,我会担心动态下载到/data文件夹-如果我不能编译9-patch文件,那么添加服务器端的工作就没有什么意义了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-06-29 02:08:13

没有简单的方法可以做到这一点afaik。9-patch编译是由aapt完成的,并且非常简单:它丢弃了黑色边框,并将其内容编码到PNG块中。对于你来说,编写一个做类似事情的工具是相当微不足道的。请注意,您甚至不需要使用相同的格式。如果您查看文档中的各种NinePatch API,您将看到您可以提交自己的“块”(它对拉伸区域和填充进行编码)。块byte[]数组的结构如下所示:

代码语言:javascript
复制
/**
 * This chunk specifies how to split an image into segments for
 * scaling.
 *
 * There are J horizontal and K vertical segments.  These segments divide
 * the image into J*K regions as follows (where J=4 and K=3):
 *
 *      F0   S0    F1     S1
 *   +-----+----+------+-------+
 * S2|  0  |  1 |  2   |   3   |
 *   +-----+----+------+-------+
 *   |     |    |      |       |
 *   |     |    |      |       |
 * F2|  4  |  5 |  6   |   7   |
 *   |     |    |      |       |
 *   |     |    |      |       |
 *   +-----+----+------+-------+
 * S3|  8  |  9 |  10  |   11  |
 *   +-----+----+------+-------+
 *
 * Each horizontal and vertical segment is considered to by either
 * stretchable (marked by the Sx labels) or fixed (marked by the Fy
 * labels), in the horizontal or vertical axis, respectively. In the
 * above example, the first is horizontal segment (F0) is fixed, the
 * next is stretchable and then they continue to alternate. Note that
 * the segment list for each axis can begin or end with a stretchable
 * or fixed segment.
 *
 * The relative sizes of the stretchy segments indicates the relative
 * amount of stretchiness of the regions bordered by the segments.  For
 * example, regions 3, 7 and 11 above will take up more horizontal space
 * than regions 1, 5 and 9 since the horizontal segment associated with
 * the first set of regions is larger than the other set of regions.  The
 * ratios of the amount of horizontal (or vertical) space taken by any
 * two stretchable slices is exactly the ratio of their corresponding
 * segment lengths.
 *
 * xDivs and yDivs point to arrays of horizontal and vertical pixel
 * indices.  The first pair of Divs (in either array) indicate the
 * starting and ending points of the first stretchable segment in that
 * axis. The next pair specifies the next stretchable segment, etc. So
 * in the above example xDiv[0] and xDiv[1] specify the horizontal
 * coordinates for the regions labeled 1, 5 and 9.  xDiv[2] and
 * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that
 * the leftmost slices always start at x=0 and the rightmost slices
 * always end at the end of the image. So, for example, the regions 0,
 * 4 and 8 (which are fixed along the X axis) start at x value 0 and
 * go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at
 * xDiv[2].
 *
 * The array pointed to by the colors field lists contains hints for
 * each of the regions.  They are ordered according left-to-right and
 * top-to-bottom as indicated above. For each segment that is a solid
 * color the array entry will contain that color value; otherwise it
 * will contain NO_COLOR.  Segments that are completely transparent
 * will always have the value TRANSPARENT_COLOR.
 *
 * The PNG chunk type is "npTc".
 */
struct Res_png_9patch
{
    Res_png_9patch() : wasDeserialized(false), xDivs(NULL),
                       yDivs(NULL), colors(NULL) { }

    int8_t wasDeserialized;
    int8_t numXDivs;
    int8_t numYDivs;
    int8_t numColors;

    // These tell where the next section of a patch starts.
    // For example, the first patch includes the pixels from
    // 0 to xDivs[0]-1 and the second patch includes the pixels
    // from xDivs[0] to xDivs[1]-1.
    // Note: allocation/free of these pointers is left to the caller.
    int32_t* xDivs;
    int32_t* yDivs;

    int32_t paddingLeft, paddingRight;
    int32_t paddingTop, paddingBottom;

    enum {
        // The 9 patch segment is not a solid color.
        NO_COLOR = 0x00000001,

        // The 9 patch segment is completely transparent.
        TRANSPARENT_COLOR = 0x00000000
    };
    // Note: allocation/free of this pointer is left to the caller.
    uint32_t* colors;

    // Convert data from device representation to PNG file representation.
    void deviceToFile();
    // Convert data from PNG file representation to device representation.
    void fileToDevice();
    // Serialize/Marshall the patch data into a newly malloc-ed block
    void* serialize();
    // Serialize/Marshall the patch data
    void serialize(void* outData);
    // Deserialize/Unmarshall the patch data
    static Res_png_9patch* deserialize(const void* data);
    // Compute the size of the serialized data structure
    size_t serializedSize();
};
票数 10
EN

Stack Overflow用户

发布于 2019-10-24 18:35:03

这是一个适用于我的情况的变通方法。

我的应用程序中有默认的9补丁图像,我将其用作消息气泡。我想创建可下载的themes,它可以改变气泡和其他东西,如字体颜色等。

可绘制文件夹中包含的*.9.png图像是默认图像,它们包含图像周围的黑色像素:

default_outgoing.9.png

“自定义”/themed气泡具有完全相同的尺寸,放置位置略有变化,仍然使用与默认区域相同的“块”区域,但这些气泡在文件名中不包括黑色像素或.9

pink_round_outgoing.png

那么,如何在自定义版本工作的同时仍然保持良好的外观呢?下面是一些代码,它获取自定义图像,从默认的9补丁图像中获取一些值,并将它们应用于自定义位图:

代码语言:javascript
复制
//Get the custom replacement image
Bitmap bitmap = BitmapFactory.decodeFile(folderpath + File.separator + "pink_round_outgoing.png");

//Get padding from the default 9-patch drawable
Drawable existingDrawable = ContextCompat.getDrawable(this, R.drawable.default_outgoing);
Rect padding = new Rect();
if (existingDrawable != null) {
    existingDrawable.getPadding(padding);
}

//Get 9-patch chunk from the default 9-patch drawable
Bitmap existingBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.default_outgoing);
byte[] chunk = existingBitmap.getNinePatchChunk();

//Finally create your custom 9-Patch drawable and set it to background
NinePatchDrawable d = new NinePatchDrawable(getResources(), bitmap, chunk, padding, null);
view.setBackground(d);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6510467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档