#2X effect for Android 9-patch - android

On iOS, you can specify #2x images that will be used in places where the pixel density (UIScreen scale) is greater than 1. You still refer to logical pixels, but the images will display using the actual physical pixels (which are usual 4x the logical pixels).
On Android, it seems like using dp to specify dimensions has a similar effect. For example, a layout such as the following
<TextView
android:layout_width="50dp"
android:layout_height="25dp"
android:id="#+id/MessageTextView"
android:background="#drawable/messageBackground" />
If the image messageBackground is a higher resolution than 50x25, the platform scales it appropriately when displayed on a screen with higher density, using the additional pixel information to fill the increased pixels. (At least that is how it appears to me).
My question, however, relates to nine patched images. These are the images that stretch based on the actual size that they are displayed over.
nine patched images I have not been able to figure out how to make them 'scale up' on higher density screens. As you'd expect, the expandle portion of the nine patch stretches to make an image larger. But the 'fixed' portions of the nine patch are just displayed using dp pixels, not actual pixels.
Is there a way to use a higher res image with nine patch, such that the 'fixed' portions of the image display at the full resolution of the device? I don't want the higher res version to just appear larger, I want it to display it's natural size using all the available pixels for the best possible image.

Is there a way to use a higher res image with nine patch, such that the 'fixed' portions of the image display at the full resolution of the device?
Yes. See Providing Resources and Supporting Multiple Screens documentation on the Android developers site.
You need to create your resources at multiple resolutions, then you simply drop them into the appropriate drawable folders for that density bucket.
Essentially, the drawables-mdpi folder is the one to use for your standard 1x resources. drawables-xhdpi is your 2x. You probably want to provide your drawables at mdpi, hdpi, xhdpi, and xxhdpi to provide appropriate quality resources for the vast majority of Android devices.

Related

Android: Create an image that covers the screen for different displays

I want to add a background image to one of the screens of an Android app. (This image is a photo so 9-patch will not work).
I want scale this image for various different resolutions.
Android organises images uses DPI (i.e. ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi). However this does not seem useful in this particular situation as I want to use an image that covers the ENTIRE screen. DPI does not tell me how big the entire screen is. For example, a xxxhdpi screen may have a lower resolution than a ldpi screen.
To illustrate this issue consider the following devices:
Samsung Galaxy Tab 10: mdpi, 800px x 1280px
Moto G: xhdpi, 720px x 1280px
As you can see the first device requires a larger resolution image, despite having a lower dpi.
Therefore my question is, how do I create an image that covers the screen for different screen sizes.
You can find several answer at stackoverflow like: Android: Background Image Size (in Pixel) which Support All Devices
Another reference including tablets can be found at: Is there a list of screen resolutions for all Android based phones and tablets?
The detailed description can be found at: https://developer.android.com/guide/practices/screens_support.html
One point you need to keep in mind is how the image will cover your layout, you need to fit using center crop as scale type.
Remember to leave some space from borders at least not including important information that could be cropped from the border based on the real device size.
Another way to add backgrounds for multiple size and densities is not trying to cover the entire scree just a mix. A gradient plus some image can give you enough flexibility many times.
Another solution is using a blurred image which do not interfere with the rest of the information shown. In this case because of the nature blurred of the image, it is not required to be detailed.
Hope it helps.

Do I need to add different sizes of the same drawables even though each of them has multiple DPI versions?

I am using the "Icon Pack Drawable Importer" plugin which I think is probably importing the icons from "https://design.google.com/icons". Each icon has many sizes (18dp, 24, 36, 48...) and for each size, there are multiple DPIs (mdpi ~ xxxhdpi) for it.
This is a little bit confusing, because as far as I know on Windows, you just define multiple resolutions of the same icon, and the system will automatically choose the closest resolution (best) version for the actual drawing size.
Suppose I want to display two arrows in two different sizes on the same device. Suppose I only added one arrow icon whose size is 48dp but has 5 different DPI versions in it. If I specified the final drawable size programmatically, does Android select the closest one? For example, mdpi version for the small arrow and the xxxhdpi version for the large arrow? Or does Android select one version that matches the system's DPI and resize and use it for the two arrows?
I want to let users choose the icon size for them (some may want big, some may want small), but adding multiple size versions of one icon which itself has DPI versions seems a little bit complex. So, I thought of adding the biggest size only (48dp version, but it has 5 DPI versions in it) and specifying smaller resolution programmatically if the user wants smaller icon, because upscaling would make an icon blurry but downscaling would not. Is that a bad idea, and should I add multiple sizes and multiple DPIs of the same icon to the resources?
If your screen is mdpi, all your drawables will be loaded first from res/drawable-mdpi directory, then, if the file is not found, from res/drawable directory. So if you resize 24x24 mdpi icon programmatically to 64x64 pixels, you will get degraded picture quality, Android will not load xxdpi icon for you instead.
If you set all your icon sizes in a programmatic way, simply select the highest-resolution icons and dump them all into res/drawable directory.
Icons in res/drawable-mdpi still has the advantage that they use less memory and don't need to be mipmapped, however modern phones can resize all graphics, with smoothing and mipmapping applied, in hardware.

Resources for multiple screen sizes

As far as I know it is possible to provide multiple resource paths for multiple dpis (mdpi, hdpi etc.). What if I want to support multiple screen sizes at the same dpi?
For example, if I have an application that draws an icon whose size is always a percentage of the screen size (e. g. 25 %) and I replace the screen by a larger one with the same dpi, then the icon has to be scaled up. This will make the icon blurry unless I provide a version with a higher resolution. Since Android only distinguishes by dpi and not by screen size, how can I do this?
If the icon is included in the APK, you may as well just put just one copy - the highest resolution you have. Large icons can be scaled down just fine, it's scaling small icons up that causes the blurriness. The reason for including different sizes is to save bandwidth when icons are downloaded, but since all the copies would already be on the device, in effect all you will be doing is making the APK bigger. First prize would be to include a vector image (infinitely scalable, small size).
You should also note that the blurriness is really only in comparison with the sharpness of the rest of the display. In reality the 2x scaled-up icons would look just as good as the same icons on a display with a density half as much.
If, however, you still want to select a certain copy of an image based on the dpi and screen size, there are ways you can detect this in Android. See this SO question, for example.

Android layout on high density displays

i just released my app on android and have problems with customers with high density displays.
i added a debug thing to see what's going in, here is one sample output
Device: Nexus 10 Android version: 4.2.2
DisplayMetrics{density=2.0, width=2560, height=1504, scaledDensity=2.0, xdpi=298.275, ydpi=298.823}
MainView w=1900 h=1342
mDrumKitMode=BIG
KitView w=640 h=1266 x=1920.0 y=0.0
the main view is the music notation area on the left of the screen shot, its 1900 wide (MainView w=1900 h=1342) the drum kit is a bitmap that is 640w and 640 high. somehow, the display is scaling it to be full height of the parent, (KitView w=640 h=1266 x=1920.0 y=0.0). this doesn't happen on displays where density=1.0.
i have no way to test this since i can't get the emulator work on big displays for some reason and i don't have a high density tablet.
does anyone have an idea what could be going on? thanks
and here's another customer with a similar problem
Device: A700 Android version: 4.1.1
DisplayMetrics{density=1.5, width=1920, height=1128, scaledDensity=1.5, xdpi=224.73732, ydpi=224.11765}
MainView w=1260 h=1044
mDrumKitMode=BIG
KitView w=640 h=968 x=1280.0 y=0.0
i think its the scaledDensity=1.5 parameter, maybe i need to do something to disable automatic image scaling, i.e. set scaledDensity=1?
i should add that the entire application is based on exact pixel positions, both for the music notation display and the drum kit display which overlays images on top of the base drum kit image (you can see the drum pedals are in the wrong place on this image too). i don't want automatic scaling as i handle scaling inside the app for different display sizes and user preferences.
i should also add that all my drum kit images are in drawable-mdpi and all the other dpis are empty. this is because i scale images programmatically based on screen size and user preference BUT i think maybe the problem is a need to put some images in xhdpi? i guess i can do that but it will be a lot of work.
PS, i guess i found my answer here http://developer.android.com/guide/practices/screens_support.html
Provide different bitmap drawables for different screen densities
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.
i wonder if simply copying all the -mdpi images to -xhdpi will work?
If you intend for this app to be used across devices you have no choice but to put in images for all the various density folders that exist (xhdpi,xxhdpi, hdpi, mdpi). It's also worth considering that you may want to change the actual layouts you include, to offer different ones for different devices.
Consult the documentation for how to handle this.
http://developer.android.com/guide/practices/screens_support.html
If that creates an apk that's too heavy (I have no idea how many images you have) then you can go the other way and specify a no scaling drawable folder which will just use the images in their native density across devices. It's definitely wrong to use ONLY mdpi unless you intend to support only mdpi devices.

Handling image resource size on Android

I am kind of confused about managing graphic resources in Android.
Tried to read this doc but It only confuses me more. Can anyone give me some example of how should I handle the following case?
Lets assume that I have an image in my layout that will be scaled to fill screen width. What image sizes (in pixels) should I produce and what configuration qualifiers (drawable-{qualifier}) should I apply to those resources to cover all major dpi and screen sizes (both for tablet and handset)?
Thanks.
If you want to have an image, that is supposed to fill the screen it is best to use 9-patch images. This way your image can automatically scale to fit the device. Because even if an image has the correct density, the actual screen size can vary. For example a smartphone and a tablet can both be hdpi, but have completely different screen sizes (and actual pixel count).
So the easiest way to target most devices, when it comes to images that are supposed to fill up the full width of the screen is to have a 9-patch image and create ldpi, mdpi, hdpi and xhdpi versions of it. This way the image will automatically be choosen depending on the density and then stretched to fit the device.
The android sdk also provides a tool that helps with creating 9-patch images http://developer.android.com/tools/help/draw9patch.html

Categories

Resources