It is common that we provides various densities drawables in the project
drawable-mdpi
drawable-hdpi
drawable-xhdpi
drawable-xxhdpi
drawable-xxxhdpi
I was wondering, should we favor Vector drawable over multiple densities drawable?
I went through https://developer.android.com/training/multiscreen/screendensities#vector-graphics .
But, it doesn't mention when should we use multiple densities drawable, and when should we use Vector drawable. Is there any situation when Vector drawable is not favorable?
Vector drawables should always be favoured where it is possible to replace the image with a vector as it is completely scalable.
The only place where you would use an image with different densities is when the image cannot be represented by a vector drawable.
Vector drawables are natively supported in API 21 and up (Android 5) and you won't need to use any special library to be able to use them in your app. For example in the Image tag you can use the src attribute to load vectors just as you would use them to load bitmap images.
They can also be used in older versions of Android with the help of Google support library but there will be a big performance hit.
According to Android documentation:
An alternative to creating multiple density-specific versions of an image is to create just one vector graphic. Vector graphics create an image using XML to define paths and colors, instead of using pixel bitmaps. As such, vector graphics can scale to any size without scaling artifacts, though they're usually best for illustrations such as icons, not photographs.
So vector drawables are always a better choice then using multiple densities.
This documentation will help you further:
https://developer.android.com/studio/write/vector-asset-studio
https://developer.android.com/guide/topics/graphics/vector-drawable-resources
Related
I realise that Android will try it's best if it does not find an icon in the required folder but I see someplaces they suggest all of the above and in others they don't include drawable ?
So should I populate drawable as well if all the others are filled with my tab icon images?
If you use a VectorDrawable, you don't need to add a Resource for every density (mdpi, xhdpi etc). VectorDrawable is supported since API 21 (Lollipop) or with Support Library (or AndroidX).
For simple types of images (usually icons), you can avoid creating separate images for each density by using vector graphics. Because vector graphics define the illustration with geometric line paths instead of pixels, they can be drawn at any size without scaling artifacts.
For images (PNG) on the other hand, you must add proper icons for every density because Android will try to scale the images (so they can proportionally occupy same area in all devices). When scaling, the image may become blurred reducing the quality of your UI.
To provide good graphical qualities on devices with different pixel densities, you should provide multiple versions of each bitmap in your app—one for each density bucket, at a corresponding resolution. Otherwise, Android must scale your bitmap so it occupies the same visible space on each screen, resulting in scaling artifacts such as blurring.
You can read more HERE and HERE
EDIT
Maybe, you don't need to duplicate ALL icons. A lot of factors can lead to different experiences such as using wrap_content or a specific dimension to control the icon size or even using a different scaleType in your ImageView. So, maybe, you can start by adding icons for xhdpi or xxhdpi folders only and check your screen in different screen (small display, large displays, low-resolution displays, high-resolution displays etc). Then, you can "duplicate" only the necessary icons... But if your project or APK size is relatively small, don't mind to duplicate the icons.
There's even some online tools to generate the assets for every density from a single PNG such Android Asset Studio website..
If you are adding all resolution drawable icon like :
drawable-mdpi
drawable-hdpi
drawable-xhdpi
drawable-xxhdpi
drawable-xxxdpi
then you need not to add any extra icons on drawable folder
because all the device resolution covers under the above drawable folders
I made all the drawables for my android app, and it is in xxhdpi folder. How can I make sure that the app will downsize the drawables according to the resolution phone?
you can use this link
https://romannurik.github.io/AndroidAssetStudio/nine-patches.html for converting your image to the 9 patch images and down load it in .rar format. Extract it and paste into resource folder.by using 9 patch images are chooses according to the resolution of the device..
and if you want to take the icons you can use vector drawable . it will help to reduce your app size and best for all resolution devices.
for taking Vector Drawable
Right click on Drawable --> New --> Vector Assest .
If you do not want to scale the drawables manually and put in the right folder (e.g. -mdpi, -ldpi, ...), then the best solution could be use SVG format. Read more about this topic here.
Another benefit of using SVGs is that your app will use less space on the device.
Is there any way to use only two sets of drawables, one for xxxhdpi and xxhdpi and the other one for xhdpi/hdpi/mdpi/ldpi without having to create 6 drawable-{dpi} folders and duplicating the files.
You can.
Use SVG Images instead of PNG or normal extension pictures.
Then use the following link to convert the SVG to Vector.
Use vector as your drawable, your drawable (single) will support multiple devices.
Cheers!
Vector drawables are the stuff you mean. The limitation is that it is mostly used for drawing simple shapes.
You can sue it like this. Make a vector drawable for xxhdpi and it'll be used for all resolution sizes with suitable sizes automatically. This technique is currently being used to decrease apk sizes reasonably.
I'm trying to use a VectorDrawable on API21, but Android loads the PNG resource from xxhdpi folder instead.
My current res structure as follows:
res
drawable-xxhdpi
test_icon.png
drawable-21
test_icon.xml
And my XML layout:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/test_icon"/>
Are there any other ways to solve this? From my understanding Android will always pick the PNG resource, but if that's the case, how one can use VectorDrawables for API21 and PNG for lower API's?
[Update 1]
If we use a drawable-xxhdpi-21 resource folder, Android will pick the vector instead of the PNG resource. But that means we would have to have a copy (or symlink) of the file for other densities as well (e.g. xhdpi, hdpi, etc)
drawable-anydpi-v21 is right for that
drawable-anydpi-v21/test_icon.xml
https://google.github.io/material-design-icons/#icons-for-android
The solution I found is a bit of a hack but seems to work. Instead of putting your VertorDrawable xml files in each of the bucket with the version, if you put them in drawable-w1dp-v21 it takes the right resource and don't need to have multiple copies.
This is because, when deciding which resource to use, Android checks the density and after the minimum width density, which in this case is always gonna be more than 1dp :)
Update: as #pengrad mentions best to use the anydpi bucket. :)
I am creating an android application in which I want multiple screen support.For these I have used 9 patch images.
But my question is this whether using 9 patch images will be enough for different-2 density's devices or I will need to create different-2 9 patch images for varying densities(like mdpi,ldpi,hdpi).
Thanks in advance
I recently found out myself in the same situation so let me pitch in and expand on what has been said already...
Yes, 9-patch images will scale, that's what they exist for. But if you should use a 9-patch image for all screen densities, that depends on the image really. 9-patch images are more commonly used, for instance, buttons. You can have different sized buttons in your app and a 9-patch image will help deal with them, no matter how you size your button (as long as the 9-patch image is properly created).
But let's say your button design has some really round corners for the hdpi version. You create your 9-patch image without messing the corners but when you look at it in the ldpi version, you'll realize your corners are too big for that low resolution. For this situation, you'll need a different 9-patch image with less round corners, that look better on that resolution.
So, the final answer is, it really depends on your image. If you can create a 9-patch image that looks good in all densities, than fine, use it, as you only need one image to handle all densities. But if it doesn't look good, because of corners, gradients, or whatever, than you'll need one 9-patch image for each screen density.
Hopefully it's clearer now.
From documentation: nine patch
A NinePatchDrawable graphic is a stretchable bitmap image, which Android will automatically resize to accommodate the contents of the View in which you have placed it as the background. An example use of a NinePatch is the backgrounds used by standard Android buttons — buttons must stretch to accommodate strings of various lengths. A NinePatch drawable is a standard PNG image that includes an extra 1-pixel-wide border. It must be saved with the extension .9.png, and saved into the res/drawable/ directory of your project.
the answer is no. you nine patch will scale between different screen size
Short answer is YES.
Check this:
By default, Android scales your bitmap drawables (.png, .jpg, and .gif files) and Nine-Patch drawables (.9.png files) so that they render at the appropriate
physical size on each device. For example, if your application provides bitmap drawables only for
the baseline, medium screen density (mdpi), then the system scales them up when on a high-density
screen, and scales them down when on a low-density screen. This scaling can cause artifacts in the
bitmaps. To ensure your bitmaps look their best, you should include alternative versions at
different resolutions for different screen densities.
from Android Developer Official Doc