1
votes

Hello I am new in android programing so I want to know:

How to use drawable to compatible with all screen sizes (idpi, mdpi, hdpi, xhdpi, xxhdpi)

Actually I am confused about drawable screen sizes compatibility with all screen sizes

so I want to know that:

If I want my app to compatible with all screen size do I need to put images in every drawable folder

for example: background image

  • • drawable-ldpi ( 240x320 for QVGA Device 2.7 ) put image with this resolution
  • • drawable-mdpi ( 320x480 for HVGA Device 3.2 ) put image with this resolution
  • • drawable-hdpi ( 480x800 for WVGA Device 4.0 ) put image with this resolution
  • • drawable-xhdpi ( 1280x720 for WxVGA Device 4.7) put image with this resolution
  • • drawable-xxhdpi ( 1080x1920 for Nexus 5 Device ) put image with this resolution

or I can use a single same image for all screen sizes.

5
You have to make different images and put each in a different folder. All images will have the same name, but different sizes and resolutions. You can also make (but I discourage you to) a unique xxhdpi folder, with 480 dpi graphics in it. I discourage you, because Android scaling is 1: more expensive in CPU usage terms, 2: it leads to worst resultsPhantômaxx

5 Answers

6
votes

You do not need to create an image in every possible drawable folder. It's enough to provide one image only and put it into drawable folder. This image will be scaled automatically, depending on your usage.

This will not provide good quality on all screens though and may be more expensive to compute (scale). It is recommended that you can provide separate images for different screen densities (e.g. drawable-mdpi, drawable-hdpi, etc.) and the idea is that they should have different resolutions matching the screen densities.

2
votes

Your images will only look sharp and crisp if you provide drawables for every dpi. Ldpi is no longer supported so you can ignore ldpi.

Also, for your launcher icon, provide an xxxhdpi image. Tablets running on Kit Kat with full hd screens use these images in the launcher.

Creating 1 drawable and putting it in the drawable folder is bad practice! Your images will look blurry.

1
votes

I have got a very good method for this situation works like a charm. You only need to create one hd image for you and than method works-out everything.

Here is the method:

/**
 * Get DRAWABLE with original size screen resolution independent
 * @param is Input stream of the drawable
 * @param fileName File name of the drawable
 * @param density Density value of the drawable
 * @param context Current application context
 * @return Drawable rearranged with its original values for all
 * different types of resolutions.
 */
public static Drawable getDrawable(InputStream is, String fileName, int density, Context context) {
    Options opts = new BitmapFactory.Options();
    opts.inDensity = density;
    opts.inTargetDensity = context.getResources().getDisplayMetrics().densityDpi;
    return Drawable.createFromResourceStream(context.getResources(), null, is, fileName, opts);
}

Here, you must prepare the inputstrem for your image file and set a density that is good for your screen at any usage area of yours. The smaller density is the lower quality, solve out by changing the value. Here are some examples on using the method:

1) Open an asset from the assets folder:

getDrawable(assetManager.open("image.png"), "any_title", 250, context)

2) Open a drawable from the drawables folder: Here first, you must provide your inputstream with this method: a) method:

/**
 * Get InputStream from a drawable
 * @param context Current application context
 * @param drawableId Id of the file inside drawable folder
 * @return InputStream of the given drawable
 */
public static ByteArrayInputStream getDrawableAsInputStream(Context context, int drawableId) {
    Bitmap bitmap = ((BitmapDrawable)context.getResources().getDrawable(drawableId)).getBitmap();
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] imageInByte = stream.toByteArray();
    return new ByteArrayInputStream(imageInByte);
}

and the usage: b) usage:

getDrawable(getDrawableAsInputStream(getBaseContext(), R.drawable.a_drawable), "any_title", 250, context)

I hope it is useful.

0
votes

you have to create an image in several sizes. for example: Let's say that you have ImageView with 48dp x 48dp. Base on this size you have to create image with sizes:

  1. 48x48px(100% - mdpi)
  2. 64x64px(150% - hdpi)
  3. 96x96px(200% - xhdpi)

    and so on, if you have to support more.

NOTE: there is no need to create ldpi (75%) resolution image, because your hdpi will simply scale down twice.

If you use one size for several dpi, then there can be poor quality on some resolutions.

0
votes

You can also use the Android Asset Studio, where you can upload an image and it will generate all of the types of resolution images you need. It can even be used to create animations and icons for your application. Here is the link: https://romannurik.github.io/AndroidAssetStudio/index.html