How to make ImageButton in Android automatically scale based on screen density? - android

I have an image put on an ImageButton, which looks good on a mdpi (medium-dpi) screen. However, when the device has a hdpi (high-dpi) screen, the image is still pixel-by-pixel accurate, which look small on the device screen.
How do I make such that the image (and therefore the ImageButton) scaled based on the density-independent pixels (dp or dip) instead of pixels?

android:scaleType="fitXY"
Other choices include :
fitStart
fitCenter
fitEnd
center
cenerCrop
centerInside
matrix
Mind you i'm lazy and use really large PNG images in a raw folder.

As ponkin mentioned, 9-patches are your best bet. Combined with resource directory qualifiers (drawable-hdpi, drawable-mdpi, etc.) you can make assets that look good at any density and size.
An example of 9-patches and resource directory qualifiers can be found in the Multiple Resolutions Android SDK sample. The semi-transparent, black, rounded-corner background is implemented as a 9-patch with different PNGs for ldpi, mdpi, and hdpi.

IMHO you should look pretty close to NinePatchDrawable
. There is, actually, a tool that will help you to make your icon(pictures/icons/whatever...) resizable depending on size of container. It`s really simple and works just fine for my needs. Also look at this article(part "NinePatchDrawable"), it explains the NinePatchDrawable mechanism.
A NinePatchDrawable graphic is a stretchable bitmap image, which
Android will automatically resize to
accomodate 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.

Maybe you should just specify button size in device-independent-pixels?
android:layout_width="300dip"
android:layout_height="50dip"

Related

Do I need to use all of drawable, drawable-mdpi, drawable-hdpi, drawable-xhdpi, drawable-xxhdpi & drawable-xxxhdpi?

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

Android Appropriate Image Resolution for ImageView

What is the proper/right resolution for Image to be put using src in ImageView to avoid stretching or unscaled images?
if you are using a single color of background, u can use 9Patch images. but if you are asking about icons then you need different images for different resolutions in drawable folders like drawable-hdpi for hdpi devices drawable-xxhdpi for xxhdpi devices.
for more detailshttp://developer.android.com/training/basics/supporting-devices/screens.html
To understand the image size check out the following link image size (drawable-hdpi/ldpi/mdpi/xhdpi) . To avoid stretching use "android:scaleType="fitcenter/fitxy/centercrop"" for more detail check this http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
Actually it totally depends on your placeholder or your needs, rather than single image you can make different sizes of image for different dp like small,large,normal,x-large .
probably https://romannurik.github.io/AndroidAssetStudio will save your time or new Android studio 2's built in plugin.
More resource
http://developer.android.com/training/basics/supporting-devices/screens.html

To have multiple nine-patch images or just one? If one, where to put it?

So far, I always created one nine-patch image and place it inside /res/drawable-hdpi.
But I saw some large projects which have multiple nine-page images, scaled and placed inside multiple res/drawable-xxx directories. Is this the wrong approach? Nine-patch was supposed to stretch across all screens, regardless of its DPI.
Also, if I am right and only one nine-patch is to be used, what is its default location - drawable-hdpi, mdpi, or some other directory inside /res?
Well, it really depends on quality.
If your image is just a square border, it can be a 72 dpi low res image put into the drawable folder and it would be enough.
If your image has rounded corners or other fancy elements that have to be scaled properly, you could make a 480 dpi version and put it in the drawable-xxhdpi folder. This will scale down (don't even think of scaling up, because of stretching/pixellating) good enough in most cases.
If you want the best quality in scaling, then make a version for each dpi drawable folder.
If you go to http://developer.android.com/guide/topics/resources/drawable-resource.html, you can see it there (citation):
file location:
res/drawable/filename.9.png
The filename is used as the resource ID.

Ideal dimensions of a ninepatch background

I want to create a ninepatch background file (the background is a gradient image). I would like to know what are the ideal dimensions of the background image?
In addition to that, where should I put the image: drawable-ldpi, drawable-mdpi or drawable-hdpi?
Check your SDK folder inside: /platforms/android-X/data/res/drawable-hdpi
You will notice there are a bunch of 9patches there. I understand that you should provide a 9patch for each type of device. So you should have a 9patch for ldpi, one for mdpi and one for hdpi.
The idea is to make it as small as possible and also take into account that the 9patch doesn't go smaller than the original.
On the other hand, I don't think that a 9patch will be useful when dealing with gradient images.
I would try using a GradientDrawable.
I think its 40dip x 40dip or 60px x 60px.

How to use 9 patch images in android for different-2 densities(like mdpi,ldpi,hdpi).?

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

Categories

Resources