Android:如何从输入流创建9patch图像?

时间:2012-02-14 21:57:38

标签: android

我使用以下代码实例化9patch图像并将其设置为按钮的背景。下图显示了非理想的结果。

InputStream = MyClass.class.getResourceAsStream("/images/btn_default_normal.9.png");
Drawable d = NinePatchDrawable.createFromStream(in, null);
button.setBackgroundDrawable(d);

enter image description here

尝试下面的代码,这似乎导致由本机android代码引起的ANR。现在还不是很清楚会发生什么,但应用程序存在而没有警告,日志说明了一些ANR,我在日志中看到了以下堆栈跟踪。

InputStream = MyClass.class.getResourceAsStream("/images/btn_default_normal.9.png");
Bitmap bitmap = BitmapFactory.decodeStream(in);
byte[] chunk = bitmap.getNinePatchChunk();
NinePatchDrawable drawable = new NinePatchDrawable(bitmap, chunk, new Rect(), null);
button.setBackgroundDrawable(drawable);



 at android.graphics.NinePatch.validateNinePathChunk(Native Method)
at android.graphics.NinePatch.<init>
at android.graphics.drawable.NinePatchDrawable.<init>

3 个答案:

答案 0 :(得分:3)

createFromStream()方法是Drawable类的一部分(NinePatchDrawable扩展)所以它返回一个简单的Drawable对象,而不是九个补丁。这就是为什么你的按钮看起来像我怀疑的那样。

您尝试制作九个补丁的图像在哪里?从您的示例中可以看出,它可能包含在您的应用程序资源中(可能在其中一个可绘制文件夹中?)如果是这种情况,是否有理由使用drawable的ID对您的情况不起作用?你应该可以做这样的事情:

button.setBackgroundResource(R.drawable.btn_default_normal);

如果我遗漏了某些东西(我绝对可以。)并且有理由不能使用资源ID。从文档看起来,您的第二个代码块更接近您想要的内容。

但是您使用的构造函数已弃用。 Try using this one instead.看起来像这样:

InputStream in = MyClass.class.getResourceAsStream("/images/btn_default_normal.9.png");
Bitmap bitmap = BitmapFactory.decodeStream(in);
byte[] chunk = bitmap.getNinePatchChunk();
NinePatchDrawable drawable = new NinePatchDrawable(getResources(), bitmap, chunk, new Rect(), null);
button.setBackgroundDrawable(drawable);

第一个参数的唯一区别应该是您的Applications Resources对象。

但是,老实说,我可以发誓我曾经在某个地方读过,系统无法动态地将NinePatchDrawables作为对象使用。即使NinePatchDrawable对象存在,我的印象是它不起作用/不打算成为公共API的一部分

编辑:

这个问题的答案有帮助吗? Create a NinePatch/NinePatchDrawable in runtime

此外,我在这个问题底部的回答提醒了我,为什么我认为部分公共API不能正常工作/ {= 3}}说

  

返回一个可选的私有数据数组,由UI系统用于某些位图。不打算被应用程序调用。

但看起来他们还是设法让它运转起来。

答案 1 :(得分:1)

我有很多小时的乐趣,并且draw9patch实用程序生成的9patch PNG没有添加9patch块,因为它只会在PNG上绘制黑线。

如果您尝试使用不属于您资源的9patch PNG,那么无论何时调用.getChunk()或Bitmap或BitmapDrawable对象上的任何内容,您都将获得null。

9patch块在编译时(通常由Eclipse)使用aapt添加到这些PNG中。这为我通过网络检索9patch增加了另一个步骤,因为它们必须首先使用aapt进行转换。

aapt c -v -S C:\ Users \ Kevin \ workspace \ com.xyz.theme -C C:\ Users \ Kevin \ Desktop \ out

答案 2 :(得分:0)

代码可以帮助您 https://gist.github.com/knight9999/86bec38071a9e0a781ee

 InputStream is = new FileInputStream(ninePath);
 Bitmap bitmap = BitmapFactory.decodeStream(is);
 NinePatchDrawable drawable = NinePatchBitmapFactory.createNinePatchDrawable(getContext().getResources(), bitmap);
 is.close();
 getWindow().setBackgroundDrawable(drawable);