9

This is a scenario. There are folders:

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

An image (usually background, but not bound to such images only) is located in /res/drawable only.

I test the app on Galaxy S3 and the background is displayed properly. I test on HTC One X and background image is not being displayed.

If I copy the image from /res/drawable to /res/drawable-xhdpi, the One X will display image.

Thinking logically, this should not be happening, right?! If there is no image in drawable-xhdpi, then Android should look it into other folders until it reaches the default one /res/drawable and it should pull it from there.

Why is this not happening on some mobiles?

PS. I noticed the same issue with some tablets, but I cannot remember now which ones.

PPS. I mentioned background image here, but the issue is not bound to it. It also happens with other images. I am aware that xhdpi mobiles have issues with large images and I would not like you to think that the issue was with too large background image. It also happens with other images of "normal" size.

sandalone
  • 41,141
  • 63
  • 222
  • 338
  • Have you tried a drawable-nodpi folder? Doesn't help but I am curious. – Russ Hayward Dec 28 '12 at 14:06
  • 1
    Are you sure that the image is **only** in this one folder? Because if it can be found in others, then you cannot be sure that Android will look first in the `drawable/` folder. It can look in one of the other dpi folders first. So if you have an (empty?) image there then it might get rendered. – Marcin Koziński Dec 28 '12 at 14:22
  • 1
    You should not have raster images in `res/drawable/`. That directory is for XML drawables, ones that have no intrinsic "density". – CommonsWare Dec 28 '12 at 14:26
  • @RussHayward Hm, I did not try that, but I do want image to stretch. Putting it into `drawable-nodpi` would be useless in my case – sandalone Dec 28 '12 at 15:55
  • @MarcinKoziński Background image was indeed only in `res/drawable`, but others were in `hdpi` as well. Concerning other image, all of them **except one** were displayed. I am still trying to find out why this one was not as there is not logical explanation. – sandalone Dec 28 '12 at 15:58
  • @CommonsWare I keep the largest images usually in `res/drawable` and then smaller ones in corresponding `mdpi, hdpi, xhdpi` folders. What do you mean under "raster images"? I keep a normal PNGs there (no 9.png or similar). – sandalone Dec 28 '12 at 16:09
  • @sandalone: "What do you mean under "raster images"?" -- http://en.wikipedia.org/wiki/Raster_image "I keep the largest images usually in res/drawable" -- that is not an appropriate strategy. – CommonsWare Dec 28 '12 at 16:36
  • @CommonsWare Now, I am confused with your sentence "You should not have raster images in res/drawable/". Can you explain what you meant or direct me to doc explaining what you meant? Regarding keeping larger images in `res/drawable`, which resolutions should be kept there? mdpi-sized images? – sandalone Dec 28 '12 at 17:56
  • 1
    @sandalone: http://developer.android.com/guide/practices/screens_support.html "which resolutions should be kept there?" -- ideally, none. As I wrote, that directory is for XML drawables, ones that have no intrinsic "density". If you do put bitmaps in there, they will apparently be treated as `-mdpi`, probably for backwards compatibility. However, for long-term maintainability, you should put `-mdpi` bitmaps in `res/drawable-mdpi/`, so that there is no confusion. – CommonsWare Dec 28 '12 at 18:06
  • @CommonsWare I apologize, but I do not know the meaning of `have no intrinsic "density"`. Do you maybe refer do dynamically created `Drawables`? I am as well familiar with the link you provided, but thanks anyway. – sandalone Dec 28 '12 at 18:18
  • 1
    @sandalone: XML drawables are either vector art (`ShapeDrawable`) or are effectively `if`/`switch` statements (e.g., `LevelListDrawable`). None of them behave differently based upon density. XML drawables can safely go in `res/drawable/`. Bitmap images should only go in directories that specify what density Android should consider those images to be, such as `res/drawable-mdpi/`. – CommonsWare Dec 28 '12 at 18:27
  • drawable has a density class of mdpi. it's explicitly stated in the docs that mdpi is the default when none is specified. you can make up whatever policies you want about storing what where, but you can't claim it doesn't have a density class. :) – Lance Nanek Dec 29 '12 at 08:06

2 Answers2

9

why do you want to put an image file into the drawable folder ?

according to tips i've read over the internet , you should not put images files in the drawable folder .

in the drawable folder you put only xml type drawables.

if you want to put an image file , put it in any of the following folders (or add an additional qualifier for them , or use other qualifiers ) :

  • drawable-nodpi (only for images that you don't know what should be their size)
  • drawable-ldpi
  • drawable-mdpi
  • drawable-hdpi
  • drawable-xhdpi
  • drawable-tvdpi

images that are put into the drawable folder are treated as default , which is mdpi . so if you want to keep the file in the same screen density category , put it into the drawable-mdpi folder.

another reason for not putting an image into the drawable folder is that android will automatically convert the file to 16 bit image for some devices (like the samsung galaxy s) , which will make the image look awful on some cases.

here's a link that explains this issue .

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • 1
    WOW!!! Thanks, I think this explained a lot to me. I've read so much of the docs and somehow missed the real purpose of `res/drawable`. – sandalone Dec 29 '12 at 12:56
  • 1
    yes there are many types of drawables , many that i don't even know of . anyway , try to put each file into the correct folder . – android developer Dec 29 '12 at 13:00
3

I made a project with a drawable that is only in the "res/drawable" folder, tested it on my One X, and confirmed the image is displayed:
https://github.com/lnanek/Misc/tree/master/TestOneXDrawableFolder

Layout:

<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>

Resources:

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  

You can try to figure out what you are doing different that might be triggering some other behavior. Keep in mind that having a "drawable" folder and a "drawable-mdpi" folder is a little odd, because the drawable folder is mdpi density by default. It may be not be deterministic which of those two will get used. I know using a density specifier does automatically append a -v4 in modern build tools to fix problems with Android 1.5 not understanding these specifiers and handling them correctly, so drawable-mdpi-v4 might be considered to have more specifiers and match in precedence compare to drawable. Both folders have a mdpi density class anyway, however, so keep in mind your drawable from either folder will be scaled up automatically if used from there.

eggyal
  • 122,705
  • 18
  • 212
  • 237
Lance Nanek
  • 6,377
  • 2
  • 24
  • 19