为什么一些xhdpi手机无法显示位于/res/drawable文件夹中的图片?

9

这是一个场景。有以下文件夹:

  • drawable
  • drawable-ldpi
  • drawable-mdpi
  • drawable-hdpi
  • draawble-xhdpi

一张图片(通常是背景,但不仅限于此类图片)只位于/res/drawable中。

我在Galaxy S3上测试应用程序,背景正常显示。但在HTC One X上测试时,背景图片没有显示出来。

如果我将图片从/res/drawable复制到/res/drawable-xhdpi,则One X可以显示图片。

从逻辑上讲,这种情况不应该发生,对吗?!如果drawable-xhdpi中没有图片,则Android应该查找其他文件夹直到找到默认的/res/drawable,然后从那里获取图片。

为什么一些手机上不会发生这种情况呢?

PS. 我注意到某些平板电脑也存在同样的问题,但现在我记不清是哪些了。

PPS. 我在这里提到背景图片,但是问题并不局限于此。其他图片也会出现同样的问题。我知道xhdpi手机对于大型图片存在问题,但是我不希望你认为问题出在背景图片太大上。其他“正常”大小的图片也会出现这种情况。


1
你确定这张图片只存在于这一个文件夹吗?因为如果它也存在于其他文件夹中,那么你就不能确定Android会首先查找drawable/文件夹。它可能会首先查找其他dpi文件夹中的一个。所以如果你在那里有一张(空的?)图片,它可能会被渲染出来。 - Marcin Koziński
1
你不应该在res/drawable/中放置光栅图像。该目录是用于XML可绘制对象,这些对象没有固有的“密度”。 - CommonsWare
@sandalone: "你所说的“光栅图像”是什么意思?" -- http://en.wikipedia.org/wiki/Raster_image "我通常将最大的图像保存在res/drawable文件夹中" -- 那不是一个合适的策略。 - CommonsWare
1
@sandalone:http://developer.android.com/guide/practices/screens_support.html “应该保留哪些分辨率?”-- 理想情况下,不应该保留任何分辨率。正如我所写的那样,该目录是用于XML可绘制对象的,这些对象没有固有的“密度”。如果您确实将位图放在那里,它们显然会被视为“-mdpi”,可能是为了向后兼容性。但是,为了长期可维护性,您应该将“-mdpi”位图放在“res/drawable-mdpi/”中,以避免混淆。 - CommonsWare
1
@sandalone:XML可绘制对象既可以是矢量图形(ShapeDrawable),也可以是有效的if/switch语句(例如LevelListDrawable)。它们中没有一个根据密度而表现不同。XML可绘制对象可以安全地放置在res/drawable/目录下。位图图像应该只放在指定了Android应该将这些图像视为什么密度的目录中,例如res/drawable-mdpi/ - CommonsWare
显示剩余7条评论
2个回答

9
为什么要将图像文件放入drawable文件夹中?
根据我在互联网上阅读的提示,您不应该将图像文件放在drawable文件夹中。
在drawable文件夹中,您只需要放置xml类型的可绘制对象。
如果您想要放置一个图像文件,请将其放置在以下任何一个文件夹中(或为它们添加其他限定符或使用其他限定符):
drawable-nodpi(仅适用于您不知道其大小的图像)
drawable-ldpi
drawable-mdpi
drawable-hdpi
drawable-xhdpi
drawable-tvdpi
放入drawable文件夹中的图像被视为默认值,即mdpi。因此,如果您想将文件保留在相同的屏幕密度类别中,请将其放入drawable-mdpi文件夹中。
不将图像放入drawable文件夹的另一个原因是,Android会自动将文件转换为16位图像,以便某些设备(如三星Galaxy S)在某些情况下看起来很糟糕。
这里有一个链接可以解释这个问题

1
哇!!! 谢谢,我觉得这给了我很多启示。我阅读了很多文档,但不知怎的错过了 res/drawable 的真正用途。 - sandalone
1
是的,有许多种类型的可绘制对象,其中许多我甚至不知道。无论如何,请尝试将每个文件放入正确的文件夹中。 - android developer

3
我用一个只在"res/drawable"文件夹中的drawable创建了一个项目,在我的One X上测试并确认图像显示正常:
https://github.com/lnanek/Misc/tree/master/TestOneXDrawableFolder

布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    tools:context=".MainActivity">
    <ImageView  
        android:src="@drawable/drawableonly"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_centerHorizontal="true"  
        android:layout_centerVertical="true"  
        />
</RelativeLayout>

资源:

res  
res/drawable  
res/drawable/drawableonly.png  
res/drawable-hdpi  
res/drawable-hdpi/ic_launcher.png  
res/drawable-ldpi  
res/drawable-mdpi  
res/drawable-mdpi/ic_launcher.png  
res/drawable-xhdpi  
res/drawable-xhdpi/ic_launcher.png  
res/layout  
res/layout/activity_main.xml  
res/menu  
res/menu/activity_main.xml  
res/values  
res/values/strings.xml  
res/values/styles.xml  
res/values-v11  
res/values-v11/styles.xml  
res/values-v14  
res/values-v14/styles.xml  

您可以尝试找出您所做的不同之处,可能会触发其他行为。请记住,拥有“drawable”文件夹和“drawable-mdpi”文件夹有点奇怪,因为默认情况下,drawable文件夹是mdpi密度。它可能无法确定使用这两个文件夹中的哪一个。我知道在现代构建工具中,使用密度限定符会自动附加-v4,以解决Android 1.5不理解这些限定符并正确处理它们的问题,因此drawable-mdpi-v4可能被认为具有更多的限定符并且优先匹配。无论如何,这两个文件夹都有一个mdpi密度类,所以请记住,如果从其中任何一个文件夹中使用可绘制对象,则该对象将自动缩放。

尝试将这张图片作为RelativeLayout的背景添加,看看会发生什么。谢谢。 - sandalone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接