Reuse drawable images for different screen sizes and densities on Android
Asked Answered
S

5

11

Context: I'm developing an Android application for tablets (landscape) with image resources which has a resolution of 1920x1200. That resolution fits on the following screen sizes and densities:

drawable-xlarge-hdpi
drawable-large-xhdpi

Problem: If I include all my image resources duplicated on this two folders the final size of the APK will be unnecessarily heavy

My unsuccessful approach: I tried to use Alias for this drawables as defined here: http://developer.android.com/guide/topics/resources/providing-resources.html#AliasResources

I have my image resource in:

res/drawable-nodpi/image_cmn.png

and the two alias inside corresponding screen sizes and densities folders:

res/drawable-xlarge-hdpi/image.xml
res/drawable-large-xhdpi/image.xml

image.xml:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/image_cmn" />

Of course, when I use my image inside a layout file I reference the alias:

<ImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/image" />

But sadly Android is not resizing properly the resource for my testing tablet (mdpi) and the result is that I have bigger images.

I tried to move the original png's to res/drawable even to res/raw but result is the same than res/drawable-nodpi.

If I move this png's to res/drawable-xlarge-hdpi (same of xml alias) the result is correct but naturally that not solve my problem cause also I'd have to copy them to res/drawable-large-xhdpi and apk size increases.

Does anyone know how to achieve that?

Stillage answered 9/8, 2014 at 15:34 Comment(5)
normally we only use density qualifiers for drawable resources. You really don't need to add large/xlarge as these two only deal with layout resources.(BTW, I never see them used together)Gattis
@suitianshi: No, it is reasonable to have different drawables based upon screen size as well. Google does this in the platform, for example, with resource directories like res/drawable-sw600dp-hdpi/.Fromma
"That resolution fits on the following screen sizes and densities" -- 1920x1200 has little to do with screen sizes. I expect to see -normal devices running that resolution (or higher) later this year, for example.Fromma
@Fromma I'm agree, phones can have this resolution as well. In this case I only need to develop for tablets so these are the folders I needStillage
I am having the exact same problem, images are too big when using the aliases, this method is basically useless for drawables ... How can Google publish this kind of thing to production?Polysyllable
C
3

I try to avoid using wrap_content on ImageViews due to different platform versions resizing the images differently, if you put an explicit width and height in dp it doesn't matter as much which image gets selected.

In your case I would have a single image in drawable/xhdpi. Specify it's width and height in the layout file in dp. For a 1920x1200px image that would be layout_width="960dp" layout_height="600dp"

The image will be the roughly the same physical size on x-large tablets as large tablets.

If you want the image to be bigger on x-large tablets, include a second layout file where the width and height of the images are increased but keep the same images.

Alternatively you can use dimension resources that are different between large and x-large.

Cassaundra answered 13/8, 2014 at 3:52 Comment(3)
I'm afraid this will be the only solution. I'm not happy at all (with this android issue) cause this approach increases memory consumption on low resolution devices.Stillage
You could combine my approach with yours, use xml aliases to pick the image you want then use an explicit dp size in your layout to control the visual runtime resizing.Cassaundra
This approach resize all images, making them blurry..... This is not a good approach regarding quality. I am at the opposite trying to use as much as possible the wrap_content parameter to leave images at their native size. But I am still trying to find a solution to this topic.Quacksalver
T
3

I can propose two solutions for this problem:

First one:

  1. Put all your images to assets folder. Split them to folders by resolutions.
  2. Write your own logic to determine current device resolution and/or size.
  3. Pick image from folder with determined resolution.
  4. Set it to your ImageView in code.

Second one (it is ugly, but very quick):

Just compress your png images with tinypng.com. It can reduece your images up to 70-80% without losing quality (for mobile devices).

Tingle answered 19/8, 2014 at 15:19 Comment(0)
A
2

how about this:

  1. put all your image resource in res/drawable-nodpi
  2. put different layout files in res/layout-xlarge, res/layout-large, res/layout
  3. when use this image on ImageView, do not use match_parent or wrap_content, use calculated size in dp instead.

this should work, but however, the downside is that it does not use pre-scaling, meaning on lower dpi devices, it will consume more memory.

Arlyn answered 13/8, 2014 at 3:55 Comment(2)
Probably this is the only solution. But how is it possible that Android could not take this into account? I've just open an issue 74825Stillage
maybe there's another workaround, put images in asset and load it manually according to your device resolution and size.Arlyn
H
2

Okay i got your problem.i have my word related to this problem

There are two way and i recommended both.

First Way (more convenient related to your current problem. )

Upload multiple apk if size become bigger.

follow official guide.

Second way i more prefer to use this way.

Create multiple layouts. like below

res/layout/main_activity.xml ---> # For handsets (smaller than 600dp available width)

res/layout-sw600dp/main_activity.xml --># For 7” tablets (600dp wide and bigger)

res/layout-sw720dp/main_activity.xml # For 10” tablets (720dp wide and bigger)

I strongly recommended to read each word of this official doc by google.

Thanks.

Herv answered 19/8, 2014 at 14:15 Comment(0)
C
1

If you want to use same image for all size devices then i think you should use 9 patch Image with each layout contain weight tag inside linear layout in android. I think it's work 100%. I am sure. because i am using this methodology for universal application(means Tablet and Device application)

Cariecaries answered 18/8, 2014 at 4:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.