Supporting multiple screens on Android

2019-05-27 06:04发布

问题:

Have read the doc which is lengthy and still not clear.

Assuming I have an image with size = 120px * 80px, under the default mdpi/160 density, I also need to prepare

ldpi = 90 * 60
hdpi = 180 * 120
xhdpi = 240 * 160

Are the calculation above right? Assume I only have a single layout, so what I need is to prepare the images and place them under the corresponding drawable folders, right?

Thanks

回答1:

Yes, those are the correct sizes.

Yes, just put your various versions in the res/drawable-ldpi, -mdpi, -hdpi, and -xhdpi folders and you're done.

Depending on your image -- specifically whether it still looks good scaled down automatically -- you could just provide hdpi and xhdpi versions and Android will automatically scale them at run-time for ldpi and mdpi respectively.



回答2:

The image sizes you have calculated are correct based on the formula from Google:

pixels = dp * (density / 160)

Knowing the target densities of the various DPIs will allow us to calculate final image sizes:

ldpi = 120 DPI
mdpi = 160 DPI
hdpi = 240 DPI
xhdpi = 320 DPI

Here would be the correct calculation for width, starting with a medium density asset at 120 pixels wide:

ldpi  (120 DPI) = 120 * (120 / 160) == 90
mdpi  (160 DPI) = 120 * (160 / 160) == 120
hdpi  (240 DPI) = 120 * (240 / 160) == 180
xhdpi (320 DPI) = 120 * (320 / 160) == 240

Here would be the correct calculation for height, starting with a medium density asset at 80 pixels tall:

ldpi  (120 DPI) = 80 * (120 / 160) == 60
mdpi  (160 DPI) = 80 * (160 / 160) == 80
hdpi  (240 DPI) = 80 * (240 / 160) == 120
xhdpi (320 DPI) = 80 * (320 / 160) == 160

Making your final images:

ldpi = 90 x 60
mdpi = 120 x 80
hdpi = 180 x 120
xhdpi = 240 x 160

Create the following folders under res/ if they don't already exist and drop the correct assets in:

  • drawable-ldpi
  • drawable-mdpi
  • drawable-hdpi
  • drawable-xhdpi


回答3:

Edit: Ok, the calculations are correct. According to the formula px = dp * (dpi / 160) from http://developer.android.com/guide/practices/screens_support.html, where pixels on mdpi = dp.

And here is some additional information:

Dpi tells you how much dots (pixels) are in 1 inch. But it doesn't tell you how much pixels the screen has in total. So, you can have a device, which has, let's say, 400 pixels width and height and the screen has a diagonal of 5 inches. With this you get the dpi value. (Using http://members.ping.de/~sven/dpi.html for example).

Now you have another, device, which has the same dpi value, but has a higher resolution and it's bigger, for example, 1000 x 1000 pixels and also large diagonale.

If you created an image for the first case, of let's say 200 x 200 pixels, it will occupy half of the screen, but in the second case it will be only 1/5 of the screen, although both devices having same dpi, and that's probably not what you want to do.

What I usually do is orientate on the resolution of devices which usually have this dpi (like hdpi -> 480x800, xhdpi -> 720x1280, etc.), and in the layout use dip in combination with scaleType "fitStart", "center", etc. to keep the images proportional. So I put images with different resolutions in ldpi, hdpi and xhdpi folders but I don't use a formula.

There's also the possibility to use screen sizes in combination/instead with dpi, in the case it's necessary:

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

This works with additional folders like dpi.

BTW. Currently it's possible to put different versions of the app in Google Play for different resolutions / screens, so the user doesn't have to download all the files (huge app size, long time downloading, etc.), only the ones necessary for the device.



回答4:

the scaling ratio of images for the ldpi,mdpi,hdpi,xhdpi is 3:4:6:8 but u think once 1)if there is mobile with ldpi small screen is there then it will be suitable for the screen. 2)if there is mobile with ldpi medium screen is there then the images appear little bit smaller 3)2)if there is mobile with ldpi large screen is there then the images appear smaller.

like this for all the mdpi,hdpi and xhdpi screens.

If there is chance of using nine patch images in your app try those images.



回答5:

Yes, the calculations on the sizes that you have made are correct.

Now, you need to put them in the respective folders of ldpi , mdpi , hdpi and xhdpi in res/drawable of your project.



回答6:

Your calculations are correct if your goal is for your image to have (approximately) the same physical size on devices of different pixel densities. The images would go in directories

res/drawable-ldpi
res/drawable-mdpi
res/drawable-hdpi
res/drawable-xhdpi

Android classifies the device into one of these general density classes (which are 120dpi, 160dpi, 240dpi, and 320dpi) and scales images according to those ratios. Since physical devices aren't necessarily exactly one of these densities, the physical size of the image can still vary slightly from device to device. Note that if you don't supply an image for a particular density, Android will generate one by scaling the default/mdpi image. Generally, the result isn't quite to the quality that you would get by providing your own image.

If you run Android Lint, it will tell you about any missing resources (such as forgetting to include a xhdpi image) and it will also tell you if your scaling calculations are substantially off. It's a nice feature to know about.

Note that this entire image scaling approach has nothing to do with screen size, only pixel density. You can also have resource folders for different screen sizes or even for different screen size/density combinations.

However, if you want an image that will display at 120 x 80 pixels regardless of the screen density, the above scheme won't work. Instead, you should put the image in the folder

res/drawable-nodpi

Android won't scale images that it retrieves from there. The result is that your image would be about 3/4" x 1/2" on an mdpi device, 1" x 3/4" on an ldpi device, 3/8" x 1/4" on an xhdpi device, etc.



回答7:

You can use this to calculate equivalent size in pixels if you know the screen density(dpi) of the device:

equivalentPixels = sizeInDP*(screenDensity/160)

where sizeinDP is the size of widget where you want to display the image. Calculate the sizes in pixels for various screen densities and put them under respective folders.

So if you have an ImageView of size 300dp X 200dp (Width X Height), and the screen density is 320dpi, the image size in pixels should be:

Width = 300*(320/160) = 600px
Height = 200*(320/160) = 400px

Hope this helps!