我对Android应用程序有一个要求,即通过从服务器端检索新的颜色和图像,图形的各个部分应可自定义。其中一些图像是9色块图像。

我找不到创建和显示这些 9-patch 图像(已通过网络检索到的图像)的方法。

检索 9-patch 图像并将其作为位图保存在应用程序中。为了创建NinePatchDrawable,您需要相应的NinePatch或NinePatch的块(byte[])。无法从资源加载NinePatch,因为/res/drawable/中不存在图像。此外,为了创建NinePatch,您需要NinePatch的块。因此,这一切都深入到了大块。
那么问题是,如何从现有的位图(包含NinePatch信息)格式化/生成块?

我已经搜索了Android源代码和Web,但似乎找不到任何示例。更糟的是,对NinePatch资源的所有解码似乎都是本地完成的。

有没有人对这种问题有任何经验?

我的目标是API级别4,如果那很重要的话。

最佳答案

getNinePatchChunk可以正常工作。它返回空值,因为您为Bitmap提供了一个“源” ninepatch。它需要一个“已编译”的ninepatch镜像。

Android世界中有两种类型的ninepatch文件格式(“源”和“已编译”)。在源版本中,您可以在各处添加1px透明边框-稍后将应用编译为.apk时,aapt会将* .9.png文件转换为Android期望的二进制格式。这是png文件获取其“块”元数据的地方。 (read more)

好的,现在开始做生意(您正在听DJ kanzure)。

  • 客户端代码,如下所示:
    InputStream stream = .. //whatever
    Bitmap bitmap = BitmapFactory.decodeStream(stream);
    byte[] chunk = bitmap.getNinePatchChunk();
    boolean result = NinePatch.isNinePatchChunk(chunk);
    NinePatchDrawable patchy = new NinePatchDrawable(bitmap, chunk, new Rect(), null);
    
  • 服务器端,您需要准备图像。您可以使用Android Binary Resource Compiler。这将使创建一个新的Android项目(将某些* .9.png文件编译为Android native 格式)的痛苦自动消除。如果要手动执行此操作,则实际上是制作一个项目并放入一些* .9.png文件(“源”文件),将所有内容编译为.apk格式,解压缩.apk文件,然后找到*。 9.png文件,这就是您发送给客户的文件。

  • 另外:我不知道BitmapFactory.decodeStream是否了解这些png文件中的npTc块,因此它可能会或可能不会正确处理图像流。 Bitmap.getNinePatchChunk的存在表明BitmapFactory可能-您可以在上游代码库中查找它。

    如果它不知道npTc块,并且您的图像被严重破坏,那么我的答案会有所变化。

    您无需编写快速的Android应用程序来加载已编译的图像并吐出byte[]块,而无需将已编译的ninepatch图像发送给客户端。然后,您将此字节数组与常规图像一起发送给客户端-没有透明边框,不是“源” ninepatch图像,不是“已编译” ninepatch图像。您可以直接使用块来创建您的对象。

    另一个替代方法是使用对象序列化向您的客户端发送ninepatch图像(NinePatch),例如使用JSON或内置序列化器。

    编辑如果确实需要构造自己的块字节数组,我将首先查看ResourceTypes.cpp中的do_9patchisNinePatchChunkRes_png_9patchRes_png_9patch::serialize()。还有一个来自德米特里·斯基巴(Dmitry Skiba)的自制npTc块读取器。我无法发布链接,因此,如果有人可以编辑我的答案,那将很酷。

    do_9patch:
    https://android.googlesource.com/platform/frameworks/base/+/gingerbread/tools/aapt/Images.cpp

    isNinePatchChunk:http://netmite.com/android/mydroid/1.6/frameworks/base/core/jni/android/graphics/NinePatch.cpp

    struct Res_png_9patch:https://scm.sipfoundry.org/rep/sipX/main/sipXmediaLib/contrib/android/android_2_0_headers/frameworks/base/include/utils/ResourceTypes.h

    德米特里·斯基巴(Dmitry Skiba)的东西:http://code.google.com/p/android4me/source/browse/src/android/graphics/Bitmap.java

    09-30 15:41