我有一个自己用来与arduino通信的应用程序。有自定义形状按钮,所以我在PNG中将它们作为单个背景绘制,添加Buttons
和android:background="@android:color/transparent"
,使它们在自定义按钮大小的顶部透明。
在此图像中,您可以看到:1。背景 - 黑色背景,深蓝色按钮绘制为单个png。 2.橙色png - 与背景大小相同,使用match parrent
选项绘制。 3.隐形按钮 - 透明选项,蓝色方块,其中有7个。
为了消除指示图像的错位,我在PNG透明背景中绘制了相同尺寸的背景。我将它们添加到res/drawable
,并将布局XML添加为ImageView
android:visibility="gone"
,布局为FrameLayout
。为了表示按下按钮,我设置了橙色自定义按钮的VISIBLE
,当arduino打开输出时,发回确认我让我走了,并设置可见另一个PNG。它需要大量的内存。图像尺寸为1478x2623。在最坏的情况下,我必须永久地只显示8张图像+背景。在onCreate方法中,我加载了所有17张图像。
为了避免OOM - 内存不足错误,我必须调整图像大小,这让我看起来很糟糕......
如果XML中的图像可见性为android:visibility="gone"
,它是否会在onCreate中加载图像?如果是这样,我应该创建,缩放它,并在需要时绘制。如何实现?
修改
做了一些改变。
这些更改使其更快,不再出现OOM错误。目前我很忙,所以需要一些时间来测试答案中建议的方法。我会尽快尝试。
答案 0 :(得分:4)
为什么你的图片如此之大?这个分辨率(1478x2623)非常庞大,保留8个内存确实会导致OOM异常。
如果您真的必须,您可以执行以下任一操作:
回答您的确切问题: 如果XML中的图像可见性是android:visibility =“gone”,它是否会在onCreate中加载图像?如果是这样,我应该创建,缩放它,并在需要时绘制。如何实现?
是的,它仍然会加载图像,因为它需要立刻显示它,是的,你应该只在你需要时解码位图。关于如何实现这一点,见上文第2点和第3点。
答案 1 :(得分:2)
只是一个建议
为什么会发生OOM? 应用程序尝试使用分辨率为1478x2623的图像。哪个是高分辨率图像。因此,当加载更多图像时,应用程序会更快地进入内存状态。 怎么避免这个? 试图在内存中保留较少数量的图像。可以使用定义大小的LRU缓存。但这不是他的问题的解决方案,因为应用程序需要在同一屏幕中显示更多图像。 现在该如何解决? 可以尝试利用9补丁图像概念。其中重复图案可以用较小的像素表示。这种方法的优点是,由于拉伸,图像质量不会下降。
试一试或考虑一下。
答案 2 :(得分:2)
你试过layer-list
吗?我认为它仅适用于这些情况,这意味着将drawable放在彼此之上。那你该怎么办?首先缩小图像大小,然后为每个按钮创建layer-list
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<bitmap
android:id="@+id/IdofNotPressed"
android:gravity="fill"
android:src="@drawable/notpressed" />
</item>
<item>
<bitmap
android:id="@+id/IdofPressed"
android:gravity="fill"
android:src="@drawable/pressed" />
</item>
</layer-list>
之后将那些drawables设置为按钮的背景。然后得到如下的参考文献:
final LayerDrawable background = (LayerDrawable) button.getBackground();
background.getDrawable(0).setAlpha(255); // this is the lowest drawable visibale when no press occured
background.getDrawable(1).setAlpha(0); // this is the top drawable which is shown as press state (orange)it is not visible by default
现在,当您想要显示按下状态时,您需要做的就是
background.getDrawable(0).setAlpha(0); // this is the lowest drawable
background.getDrawable(1).setAlpha(255); // this is the top drawable which is shown as press state (orange) now it is visible