I use a button with an image as its background, this image has a size of 30x29, but it's resized and enlarged x2 (I think). Here is the XML code of my button :
<Button
android:id="#+id/buttonBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="10dp"
android:background="#drawable/bouton_back"
android:maxHeight="30dp"
android:maxWidth="30dp" />
And in Java :
backButton = (Button) findViewById(R.id.buttonBack);
What is wrong with that ? I do the same with other buttons and there is no problem... thank you.
Are you supplying bouton_back in your resources using multiple densities? Using dp units to size your button isn't sufficient; you must also provide multiple sizes of your images:
ldpi: 120dpi
mdpi: 160dpi
hdpi: 240dpi
xhdpi: 320dpi
The conversion formula is as follows:
px = dp * (dpi / 160)
Where px is the final image size in pixels, dp is the desired size in density-independent units, and dpi is the target density.
Simplifying this formula, using the size in pixels of your mdpi images as the baseline:
ldpi = mdpi * 0.75
hdpi = mdpi * 1.5
xhdpi = mdpi * 2.0
Going back to your sample code, if you want a button that is 30dp by 30dp, you should be providing images for each density:
ldpi: 23px x 23px
mdpi: 30px x 30px
hdpi: 45px x 45px
xhdpi: 60px x 60px
I think that may be folder issue. Where have you put the image file? (possibly there would not be a problem if You have it in drawable-hdpi)
EDIT
ps - there is also a dp unit thing, which is pixel-independent.
you are using the background property, android will stretch your image depending on the device resoulution in dpi (ldpi, mdpi, hdpi and xhdpi screens), if you put your image in drawable-mdpi folder, your image will stretch according to this coefficient
Related
I have an ImageView with these attributes:
android:layout_width="match_parent"
android:layout_height="160dp"
UI developer asks me for the size of Image that I want in px. What size should I ask? Should I ask different size for different devices?
Note
I don't have an ImageView with specific height and width. My ImageView width is match_parent not a specific width.
All the answers say that I should use a converter, How can I convert match_parent to px?
According to answers, I should ask about six images, shouldn't I?
You should give highest screen density in pixels to your UI developer then scale to lower densities on your own.
Normally an android app will support screen densities ldpi at min and xxxhdpi at max.
Step1: If you want the image size is 160 x 160 dp then give the UI developer the highest image size associated with max screen density.
160 x 4 = 640x640 px (why multiply by 4? I will explain later)
Step 2: Scale the image 640x640 px to lower size based on screen densities
ldpi: 160 x 0.75 = 120x120 px
mdpi: 160 x 1 = 160x160 px
hdpi: 160 x 1.5 = 240x240 px
xhdpi: 160 x 2 = 320x320 px
xxhdpi: 160 x 3 = 480x480 px
xxxhdpi: 160 x 4 = 640x640 px
Tips: Find your image size corresponds with mdpi density screen (known as base density or 1X density) then scale to other densities by the following formula
Update: From https://material.io/tools/devices/, screen size for base density screen is 360x640 px. So your ImageView size will be 360x160 px on 1X density screen.
ldpi: 270x120 px
mdpi: 360x160 px
hdpi: 540x240 px
xhdpi: 720x320 px
xxhdpi: 1280x480 px
xxxhdpi: 1440x640 px
Why are you not using Vector drawable?
Why use Vectors?
Data can be represented in original resolution without generalization.
Graphical outputs of the images are more pleasing than the created as raster image
Another very important reason of using vector graphics rather than raster is their size. Vector objects are much smaller than raster image format. If we have the full-size image to update, the vector file might only take few kilobytes of space on your system, where the same image in medium resolution bitmap format might not place on CD ROM.
You should use SVG images in your project.
Create SVG instead of PNG files
Ok, you want to set image height of size 160dp (since it is in dp, this is the size in mdpi). So you to have to ask UI developer to make you image of height 4 times of that. Image Height = 4 * 160. After that you can use Batch drawable importer from android studio, to make image for all differrent resolutions. Hope it helps.
Different Devices has Different sizes
android:adjustViewBounds="true" is automaticaly pickup height of image
so you can this,
<ImageView
android:id="#+id/ivImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"/>
You should go with 1440x640 for largest size.
If you want to support multiple devices with multiple images you can have 5 standard image slicings.
mdpi : 360x160
hdpi : 540x240
xhdpi : 720x320
xxhdpi : 1080x480
xxxhdpi : 1440x640
I came up with these image sizes, because if you look at most common display sizes, largest of them is 1440x2960 of Samsung Galaxy S8. (I am aware of 2160x3840, but it is not main stream and I would even say its outright crazy).
In your case you have width set to match_parent which in every case of largest (or even custom) DPI, will be 1440px at most, so you can be damn sure that 99% of the time it will not exceed it. (Most current devices with 9:18 or 9:X ratio devices also feature 1440 px width in almost every case if they go more than 1080. Check out resolutions of latest devices released.)
So you can settle at 1440 px of width. Now height of your ImageView is 160dp. Which can be (as suggested by everyone else) 160*4 = 640 px for largest default DPI xxxhdpi. The reason that you should consider height for standard dpis because it is fixed to some dp (160dp) and this may change for custom dpi devices, so you can support maximum devices with this, 640px size. Hope I was clear about size suggestion.
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.
Figure 1. Relative sizes for bitmaps at different density sizes
There are several density buckets available for use in your apps. Table 1 describes the different configuration qualifiers available and what screen types they apply to.
Table 1. Configuration qualifiers for different pixel densities.
To create alternative bitmap drawables for different densities, you should follow the 3:4:6:8:12:16 scaling ratio between the six primary densities. For example, if you have a bitmap drawable that's 48x48 pixels for medium-density screens, all the different sizes should be:
36x36 pixels (0.75x) for low-density (ldpi)
48x48 pixels (1.0x baseline) for medium-density (mdpi)
72x72 pixels (1.5x) for high-density (hdpi)
96x96 pixels (2.0x) for extra-high-density (xhdpi)
144x144 pixels (3.0x) for extra-extra-high-density (xxhdpi)
192x192 pixels (4.0x) for extra-extra-extra-high-density (xxxhdpi)
Then, place the generated image files in the appropriate subdirectory under res/ and the system will pick the correct one automatically based on the pixel density of the device your app is running on:
res/
drawable-xxxhdpi/
awesome-image.png
drawable-xxhdpi/
awesome-image.png
drawable-xhdpi/
awesome-image.png
drawable-hdpi/
awesome-image.png
drawable-mdpi/
awesome-image.png
Then, any time you reference #drawable/awesomeimage, the system selects the appropriate bitmap based on the screen's dpi. If you don't provide a density-specific resource for that density, the system picks the next best match and scales it to fit the screen.
Tip: If you have some drawable resources that the system should never scale (perhaps because you perform some adjustments to the image yourself at runtime), you should place them in a directory with the nodpi configuration qualifier. Resources with this qualifier are considered density-agnostic and the system will not scale them.
Official Source: Screen Densities
This is an official size chart given by Material Design Or you can ask for xxxhpdi which is 1440 x 2960 px based image and use this site to get all the images with various densities.
When you get images with various densities, no need to specify height and width in px layout. Keep the images with same name and use match_parent. Android will automatically choose the image according to the device.
try this source code
Display display = getWindowManager().getDefaultDisplay();
String displayName = display.getName(); // minSdkVersion=17+
Log.i(TAG, "Pantalla = " + displayName);
// Tamaño en píxeles
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Log.i(TAG, "Ancho = " + width);
Log.i(TAG, "Alto = " + height);
// dpi
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int heightPixels = metrics.heightPixels;
int widthPixels = metrics.widthPixels;
int densityDpi = metrics.densityDpi;
float xdpi = metrics.xdpi;
float ydpi = metrics.ydpi;
Log.i(TAG, "Ancho en píxeles = " + widthPixels);
Log.i(TAG, "Alto en píxeles = " + heightPixels);
Log.i(TAG, "Densidad dpi = " + densityDpi);
Log.i(TAG, "x dpi = " + xdpi);
Log.i(TAG, "y dpi = " + ydpi);
// Deprecated
int screenHeight = display.getHeight();
int screenWidth = display.getWidth();
Log.i(TAG, "Alto de pantalla = " + screenHeight);
Log.i(TAG, "Ancho de pantalla = " + screenWidth);
// Orientación
int orientation = getResources().getConfiguration().orientation;
Log.i(TAG, "Orientación = " + orientation);
Yes you would need to take multiple images for different screen sizes, if you do not want to use vectors and wish to use images (png,etc.) instead.
Since you have width as match_parent, in this case take the images with the max screen width for different density buckets:-
MDPI -> 320 px
HDPI -> 480 px
XHDPI -> 640 px
XXHDPI -> 1080 px
One dp is a virtual pixel unit that's roughly equal to one pixel on a medium-density screen (160dpi; the "baseline" density).
According to the above statement , you the find the heigth for the images :-
MDPI -> 160 px
HDPI -> 240 px
XHDPI -> 320 px
XXHDPI -> 480 px
How to calculate :-
Consider, 160 dp would be 160 px in mdpi(1x).
160 dp would be 240 px in hdpi (1.5x).
and so on..
OR using the function px = dp * (dpi / 160)
For HDPI , dpi is 240
px = 160 * 240/160
px = 240
For dpi list refer this
This helped me to figure it out, and make things clear
You can refer this
ldpi: 270x120 px
mdpi: 360x160 px
hdpi: 540x240 px
xhdpi: 720x320 px
xxhdpi: 1280x480 px
xxxhdpi: 1440x640 px
Firstly I did a lot of search to understand how it work, but I don't find simples tutorials. An exemple, this view:
These are my drawables folders:
The selected device is: Pixel 5.0 1080 x 1920 (xxhdpi).
Immagine in this resolution (1080 x 1920) I set the image view on the top in blue color (Solutis) with 700px of width and 250 px of height, how I have to resize this images for each drawables folders ?
I found this informations:
LDPI - 0.75x
MDPI - Original size // means 1.0x here
HDPI - 1.5x
XHDPI - 2.0x
XXHDPI - 3x
XXXHDPI - 4.0x
And
LDPI: Portrait: 200 X 320px
MDPI: Portrait: 320 X 480px
HDPI: Portrait: 480 X 800px
XHDPI: Portrait: 720 X 1280px
XXHDPI: Portrait: 960 X 1600px
XXXHDPI: Portrait: 1440 x 2560px
Here I don't understand why when I select my vistuel device 1080 x 1920px on the Design Edit it say xxhdpi and xxhdpi is 960 X 1600px...
And what gonna be the different sizes of the image for the differents drawables ?
If someone can publish a project exemple, I wool look on, please.
Did you check the documentation? Here is the interesting part:
Density-independent pixel (dp)
A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way.
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.
This means if your device as a higher density a bigger image will been chosen.
I'm a beginner developing an Android app that needs to display a clip art type png image the full width of the screen in both portrait and landscape mode:
Portrait:
Landscape:
Would I be right in saying that in order to cater for each screen resolution and orientation I need to include the following image sizes?:
Image width: Resource folder:
xxhdpi – 1920 px drawable-land-xxhdpi
xhdpi – 1280 px drawable-land-xhdpi
xxhdpi – 1080 px drawable-xxhdpi
hdpi – 960 px drawable-land-hdpi
xhdpi – 720 px drawable-xhdpi
mdpi – 640 px drawable-land-mdpi
hdpi – 540 px drawable-hdpi
ldpi - 480 px drawable-land-ldpi
mdpi – 360 px drawable-mdpi
ldpi - 270 px drawable-ldpi
This seems overkill. The App could have a thousand of these images and thats 10 versions of each.
What is the normal approach in this scenario?
Would you scale the images to suit?
Assuming you will maintain the same aspect ratio regardless of whether the screen is in portrait or landscape orientation and you will be displaying the image via an ImageView, you will only need 4 versions of each image - xxhdpi, xhdpi, hdpi, and mdpi.
As far as the image widths go, stick with the 2:3:4:6:8 scaling ratio recommended here, in the Android Documentation. That link specifically discusses icons, but the scaling ratio holds true for all images. So if you are using an image width of 640 px in landscape on mdpi, the hdpi, xhdpi, and xxhdpi should have widths of 960 px, 1280 px, 1920 px, and 2650 px, respectively. Don't worry about a ldpi version because Android will scale down the hdpi version for low resolution devices.
Last thing, set the scale type of the ImageView to a scale type which will maintain the image's aspect ratio (CENTER_CROP or CENTER_INSIDE). See the ImageView documentation for info about setting the scale. Then once you set the image to fill up the width of the screen, the image should appear as you would like.
Which icon size will be preferable to support different screen sizes in Android? The dimensions provided:
ldpi-36*36 px
mdpi-48*48 px
hdpi-72*72 px
xhdpi-96*96 px
worked fine for launcher icon but not for icons inside the app like ImageButtons. Can anybody help me to find out correct dimensions for ImageButtons? Thanks in advance..
You should use dp instead of px. The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen.
Conversion: px= dp * (dpi / 160)
For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels.
ldpi: 24*24 px NORMAL*0.75
mdpi: 32*32 px NORMAL
hdpi: 48*48 px NORMAL*1.5
xhdpi: 64*64 px NORMAL*2
manually you can calculate your sizes using the conversion from above
After searching a lot I found the link where I got expected and useful information.
I would like to create a background image for different resolutions in Android. So I need the values (in pixel) for ldpi, mdpi, hdpi,xhdpi and xxhdpi. It is important that the image will not be blurred.
I have already read the Documentation about multiple screen support but there are sizes in dp instead of pixel.
Try follow below android icon graphy size reference for various device screen resolutin.
ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi
Launcher And Home 36*36 48*48 72*72 96*96 144*144 192*192
Action Bar And Tab 24*24 32*32 48*48 64*64 96*96 128*128
Notification 18*18 24*24 36*36 48*48 72*72 96*96
Background 320*426 320*470 480*640 720*1280 1080*1920 1440*2560
there is no full list of screen resolutions, there are no fixed values in pixels for ldpi, mdpi, hdpi,xhdpi and xxhdpi. Every android device may have different resolution. If you want to fill all resolutions you will have to create too many images. If you put them in your app, it will make the app size huge. Maybe a better approach is to use composite image for background.
According to android documentation
mdpi is baseLine size
we can use it to measure all other scales , that mean if mdpi (scale 1) equal 1 xhdpi (scale 2) should equal 2 , multiplay mdpi sizes in scale value
all sizes width x height in pixel
xxxhdpi: 1280x1920 px // 4x
xxhdpi : 960x1440 px // 3x
xhdpi : 640x960 px // 2x
hdpi : 480x800 px // 1.5 x at least 480x720
mdpi : 320x480 px // baseline = 1x
ldpi : 240x360 px // .75 x
** notice I add xxhdpi with 3.0x scale to image*
xhdpi: 640x960 px
hdpi: 480x800 px
mdpi: 320x480 px
ldpi: 240x320 px
i think it is rather easy to convert the DP into pixels in andorid java i am achieving this with this function that i created
int getPixels(Context context, float dp) {
return (int) (context.getResources().getDisplayMetrics().density * dp + .5f);
}
hopefully this is helpful for people,
and kindly do share your views on it, as i would like to get this conversion as accurate as possible, thankyou