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.
Related
I was researching a little bit on mipmap to learn more about it. However, I just ended up confusing myself even more.
In this post: Mipmaps vs. drawable folders
The reason they use a different density is that some launchers
actually display the icons larger than they were intended. Because of
this, they use the next size up.
Hence, I got the idea that with larger icons mipmap will use a higher density(scaling up).
But then in this post: Mipmap drawables for icons
However some launchers (shipped with some devices, or available on the
Play Store) use larger icon sizes than the standard 48dp. Launchers
use getDrawableForDensity and scale down if needed, rather than up, so
the icons are high quality. For example on an hdpi tablet the launcher
might load the xhdpi icon.
I concluded that for larger icons, mipmap will scale down the icons to provide higher quality.
And finally in this post:Mipmap drawables for icons by #Sergej:
What Android will do is, it will try to pick up the image from a
higher density bucket instead of scaling it up. This will increase
sharpness (quality) of the image.
Mipmap will use a higher density instead of scaling up for larger icons.
What is really going on? Thanks.
Update:
Also, in the second post Mipmap drawables for icons by #Kazuaki, I don't understand this
Different home screen launcher apps on different devices show app
launcher icons at various resolutions. When app resource optimization
techniques remove resources for unused screen densities, launcher
icons can wind up looking fuzzy because the launcher app has to
upscale a lower-resolution icon for display. To avoid these display
issues, apps should use the mipmap/ resource folders for launcher
icons. The Android system preserves these resources regardless of
density stripping, and ensures that launcher apps can pick icons with
the best resolution for display.
Even if unused screen densities are stripped, why would the launcher app have to switch to a lower resolution? The current resolution(whatever resolution it's using), isn't unused, meaning, it wouldn't be stripped and the launcher icon wouldn't have to switch resolutions.
How does this work? Thanks.
I think your confusion about #Kazuaki quote is the now deleted documentation, replaced by: https://developer.android.com/training/multiscreen/screendensities#mipmap
Like all other bitmap assets, you need to provide density-specific versions of you app icon. However, some app launchers display your app icon as much as 25% larger than what's called for by the device's density bucket.
For example, if a device's density bucket is xxhdpi and the largest app icon you provide is in drawable-xxhdpi, the launcher app scales up this icon, and that makes it appear less crisp. So you should provide an even higher density launcher icon in the mipmap-xxxhdpi directory. Now the launcher can use the xxxhdpi asset instead.
The mipmap directories provide that "do not remove when trying to make a smaller APK".
In my understanding, mipmaping is principally for scaling-down.
In OpenGL, you can set texture filtering modes. One for scaling-down (minification), another for scaling-up (magnification) (cf. An Introduction to Texture Filtering).
Scaling-down (GL_TEXTURE_MIN_FILTER):
GL_NEAREST
GL_LINEAR
GL_NEAREST_MIPMAP_NEAREST
GL_NEAREST_MIPMAP_LINEAR
GL_LINEAR_MIPMAP_NEAREST
GL_LINEAR_MIPMAP_LINEAR
Scaling-up (GL_TEXTURE_MAG_FILTER):
GL_NEAREST
GL_LINEAR
You notice that there are no options of mipmap for scaling-up, but those are for scaling-down.
So, in my understanding, if scaling-up/down is needed, the nearest higher density texture is chosen to scale-down. Only when the current magnification is higher than the highest density texture, scaling-up is done based on the highest one.
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.
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.
I making an app for tablets. and want to use a PNG file for some of the buttons. What size the button must be? Based on Android size it should be at least 48dp x 48dp and with converters 48dp is different in different sizes of android devices. This is a calculator: Link
ldpi # 48.00dp = 36.00px
mdpi # 48.00dp = 48.00px
hdpi # 48.00dp = 72.00px
xhdpi # 48.00dp = 96.00px
So Should I make 4 different files for my png files with top pixels ? for example a version with 36px x 36px for the ldpi folder? or just make the biggest size like xhdpi (96px)?
Thanks in advance.
You CAN just make one large button size and get away with it, but thats not best practice.. You should have different sized images for different resolutions.
From Android:
Although the system performs scaling and resizing to make your application work on different screens, you should make the effort to optimize your application for different screen sizes and densities. In doing so, you maximize the user experience for all devices and your users believe that your application was actually designed for their devices—rather than simply stretched to fit the screen on their devices.
More info on supporting different devices and best practices.
Android Practices
Ya. Better Use 9 patch Images as the background for the buttons. So it will expand/ behave according screen size . Check this Link .
I just use the highest resolution and let Android scale it down. Doing it this way makes the download (file) size much, much smaller than having a different image for each resolution. And the quality as it's scaled down is no worse than it would be if you scaled it down yourself in MS Paint.
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.