I understand it is best practice to have layout_width set to "match_parent" and layout_height set to "wrap_content" for each component in the UI to ensure proper scaling across devices, portrait view and landscape view. However, setting layout_height to "wrap_content" causes each element to shrink. How can I keep elements at their desired sizes and still ensure proper scaling?
Before:
After:
After
It's not a rule of thumb that you always define layout_width match_parent and height wrap_content for each component. it all depends on your design.
To provide good graphical qualities on devices with different pixel densities, you should provide multiple versions of each image in your app—one for each density bucket, at a corresponding resolution. Otherwise, Android must scale your image so it occupies the same visible space on each screen, resulting in scaling artifacts such as blurring.
There are several density buckets available for use in your apps.
ldpi Resources for low-density (ldpi) screens (~120dpi).
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra-high-density (xhdpi) screens (~320dpi).
xxhdpi Resources for extra-extra-high-density (xxhdpi) screens (~480dpi).
xxxhdpi Resources for extra-extra-extra-high-density (xxxhdpi) uses (~640dpi).
nodpi Resources for all densities.
These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen's density.
or you can use SVG vector instead of PNG it will reduce the size of APK.
https://developer.android.com/guide/topics/graphics/vector-drawable-resources
Related
I created layout-sw600dp/layout.xml and it was looking great on device A. But on device B this layout has melt and looks bad. I want to know how my layout looks in worst possible case scenario (exactly 600dp width screen)
I want to create emulator with that screen size, so I will 100% sure that my layout will be looking good on sw-600dp+ phones. Do you know what size it is?
Also, I would really appreciate and be happy if you could give me an advice how to support multiple screen sizes in a modern world.
P.S. I have pretty difficult layouts with 40+ buttons
The short answer to your question regarding the type of emulator you'd use for sw-600dp+: a 7" tablet. You can find more information here. The sw in sw-600dp is the smallest width qualifier. It means that it is only mean to be used for devices with 600dp, which is typically 7" tablets.
The longer answer to your question about how to make sure your app look good "in a modern world" is:
Rather than trying to figure out what is the "worst case scenario", you should design layouts for each of the different screen densities and device types that Android supports:
ldpi Resources for low-density (ldpi) screens (~120dpi).
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra-high-density (xhdpi) screens (~320dpi).
xxhdpi Resources for extra-extra-high-density (xxhdpi) screens (~480dpi).
xxxhdpi Resources for extra-extra-extra-high-density (xxxhdpi) uses (~640dpi).
Per the Android docs:
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 (0.75x) for low-density (ldpi) 48x48 (1.0x baseline) for
medium-density (mdpi) 72x72 (1.5x) for high-density (hdpi) 96x96
(2.0x) for extra-high-density (xhdpi) 144x144 (3.0x) for
extra-extra-high-density (xxhdpi) 192x192 (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
You would do the same thing for layouts, creating a specific layout for each of the various dimensions (be sure to put the layouts in the right directories: layout-xhdpi, layout-mdpi, etc.). Doing this will allow the device to select the correct image/layout based on the device the user is using.
If you have a 40+ button layout, you would create buttons for each layout using the above method, then create layouts for each device. It's tedious work, but it is the correct way to do layouts on Android devices.
TLDR; read the Android documents around supporting multiple screen sizes.
How can I name my resource folder for another screen size?
For example I see in google codelab something like this:
layout-h470dp
layout-w960dp
You have a few keywords that you need to know: smallestWidth (sw), Available width (w), Available height (h), Screen size (small, normal, large, xlage) and Density qualifier (ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi, nodpi, tvdpi).
When naming the package for drawables you will choose one density qualifier, for layout resources you will choose one of the others. If you choose by screen size, you just need to put the word "layout" and the size you want, like layout-small.
The minimum layout size for a small screen is approximately 320x426 dp units, for normal approximately 320x470, for large 480x640 and for xlarge 720x960.
But if you want you can specify the density you want. The formula is sw N dp or w N dp or h N dp, for example: if your layout requires a screen width of at least 320 dp you will name the package layout-sw320dp, or you your layout will work only if there is 760dp avaiable you will set layout-w720dp or layout-h720dp, depending on width or height. Have in mind that setting w or h will depend on the avaiable size, and this change with screen rotation and with persistent UI elements.
Now if you're working with drawables you will need to choose one of those when naming the package:
ldpi (~120dpi), mdpi (~160dpi), hdpi (~240dpi), xhdpi (~320dpi), xxhdpi (~480dpi), xxxhdpi (~640dpi).
nodpi = Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen's density.
tvdpi = Resources for screens somewhere between mdpi and hdpi; approximately 213dpi.
Examples of package names: drawable-ldpi, drawable-hdpi.
Some topics of the docs where you can see more details: Providing Resources, Screen Sizes, Multiscreen Screensizes, and Screen Densities.
Related question: Android Resources by Screen Size.
For example, I provide some image in ldpi, mdpi and xhdpi folder.
When I run app on device with hdpi density, which resource will it pick - ldpi or mdpi?
Taken from http://developer.android.com/guide/topics/resources/providing-resources.html#BestMatch
If no matching resource is available, the system uses the default
resource and scales it up or down as needed to match the current
screen size and density The "default" resources are those that are not
tagged with a configuration qualifier. For example, the resources in
drawable/ are the default drawable resources. The system assumes that
default resources are designed for the baseline screen size and
density, which is a normal screen size and a medium-density. As such,
the system scales default density resources up for high-density
screens and down for low-density screens, as appropriate. However,
when the system is looking for a density-specific resource and does
not find it in the density-specific directory, it won't always use the
default resources. The system may instead use one of the other
density-specific resources in order to provide better results when
scaling. For example, when looking for a low-density resource and it
is not available, the system prefers to scale-down the high-density
version of the resource, because the system can easily scale a
high-density resource down to low-density by a factor of 0.5, with
fewer artifacts, compared to scaling a medium-density resource by a
factor of 0.75.
In this case android chooses **mdpi*.
You can read more about How Android Finds the Best-matching Resource
Consider MDPI is 1. Then, LDPI is 0.75 and HDPI is 1.5. What that means is that if you have a drawable that is, say, 50x50 on a MDPI screen it will have to be ~37x37 on a LDPI screen and 75x75 on a HDPI screen.
If you do not supply special drawables for each density, Android will scale the closest one available automatically.
You should not consider the DPI of a device to have anything to do with screen size and/or number of pixels and/or resolution and/or aspect ratio. A device could be very small and have an HDPI screen or very large and have an LDPI screen
ldpi Resources for low-density (ldpi) screens (~120dpi).
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is
the baseline density.) hdpi Resources for high-density (hdpi) screens
(~240dpi). xhdpi Resources for extra-high-density (xhdpi) screens
(~320dpi). xxhdpi Resources for extra-extra-high-density (xxhdpi)
screens (~480dpi). xxxhdpi Resources for
extra-extra-extra-high-density (xxxhdpi) uses (~640dpi). Use this for
the launcher icon only, see note above.
please check http://developer.android.com/guide/practices/screens_support.html and SO answer https://stackoverflow.com/a/6373533/2826147
I want to use background image in my app.But i am so confused about different screen sizes.I found this question:
Android: Background Image Size (in Pixel) which Support All Devices
But in answer he said xxxhdpi: 1280x1920 px but Lg G3 is xxxHdpi and screen resolution: 1440 x 2560
I need a roadmap.How should be my image sizes for all screens ? (mdpi,hdpi,xhdpi etc.)
Android devices' screen sizes in pixels and screen width in inches, can differ significantly from device to device.
To address this issue, google lets you use different resources per size/density category
See here for some more info.
Generally speaking, you must put the largest size image that you want to support for each dpi in the correct folder, and let android do the resizing.
You can also check the imageView's ScaleType attribute to choose how to scale the image to fit the view.
EDIT
the reason to use the different folders and not just one large image is that the larger the image, the more memory it consumes.
For example a 1920x1280 image is nice to have on a 1920 screen, but on a 320pixels screen the extra resolution is wasted and you have a lot of wasted memory used.
An easier way is to include one single image in your drawable directory, then, in the OnCreate function of your activity, create a bitmap to fit the screen and put it in an imageview that has width and height set to "wrap_content".
This should work for any device.
Read this link. In particular, I think what you're looking for is:
To create alternative bitmap drawables for different densities, you should follow the 3:4:6:8:12:16 scaling ratio between the six generalized densities. For example, if you have a bitmap drawable that's 48x48 pixels for medium-density screens, all the different sizes should be:
36x36 (0.75x) for low-density
48x48 (1.0x baseline) for medium-density
72x72 (1.5x) for high-density
96x96 (2.0x) for extra-high-density
180x180 (3.0x) for extra-extra-high-density
192x192 (4.0x) for extra-extra-extra-high-density
and also:
xlarge screens are at least 960dp x 720dp
large screens are at least 640dp x 480dp
normal screens are at least 470dp x 320dp
small screens are at least 426dp x 320dp
How to define different style for same layout according to screen size.
Is there any way to define such thing, except from different layout folder for different screen size.
I haven't found any other way to support different screen.
Use different folder for different screen resource:
ldpi Resources for low-density (ldpi) screens (~120dpi).
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra high-density (xhdpi) screens (~320dpi).
You better have a look here.
You can have different values folder as you have different layout folder
such as values-large, values-land, values-large-land