2
votes

Short Question

I have a 50dip by 40dip button in my Android XML layout. What are the pixel dimensions of the drawable that I need to place in my mdpi resource folder?

Long Question

Let's say I have a 50dip x 40dip button.

<Button
    android:layout_width="50dip"
    android:layout_height="40dip"
    android:background="@drawable/someImage" />

I am satisfied with the physical size of this button on my phone. My question is when I'm designing someImage.png in Photoshop, how do I decide on the pixel dimensions of the image? Currently, I'm just making it a gigantic 500px by 400px image and placing it in the the default drawable resource folder because it's working okay across all the phones and tablets I've tested on.

The reference page on supporting multiple screens does not tell me how to decide the pixel dimensions.

Problem #1 - Baseline graphic

enter image description here

This diagram only tells me the relative dimensions of the graphics I need to put into each drawable resource folder. However, it does not tell me the pixel dimension I need to make my baseline mdpi graphic, from which all other graphics are relative to.

Problem #2 - screen density fragmentation

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 little tidbit tells me that a 50dip wide graphic on a 160dpi screen will appear to be 50px wide. So great, you say. I should make my mdpi graphic (160dpi falls under mdpi) 50px wide in Photoshop. Well, it's not that simple, because not all mdpi phones are 160dpi. What if my mother's mdpi phone is 167dpi? Then my 50dip wide graphic would appear as 52.1875px on her phone, which would likely cause some weird blurring artifacts. So what am I supposed to do? Should I model my baseline mdpi off of my mother's 167dpi phone or should I model it off of the perfect laboratory 160dpi phone which maybe doesn't even exist in the real world?

3

3 Answers

0
votes

I base all my graphics off using 320x480 as the total screen size. Pixel density does not really play a role until I'm ready exporting the other density graphics. That ends up being 480*1.5 and etc.

To make another point, when you are doing 50dip x 40dip what you are really saying is 50px x 40px using a 320px x 480px baseline. Android will scale images to a certain extent for you so what you were doing does not look half bad. What you should do in this case is make a 50px x 40px button for mdpi, and make a 75px x 60px(these are x 1.5) for hdpi etc.

0
votes

When it comes to problem #2...

Should I model my baseline mdpi off of my mother's 167dpi phone or should I model it off of the perfect laboratory 160dpi phone which maybe doesn't even exist in the real world?

You should model it aiming at the perfect laboratory 160dpi phone. This is pretty much what that article is trying to tell us. My reasoning is that ldpi, mdpi etc are 'generalised' densities and it is the responsibility of the Android OS's graphics engine to correctly compensate for actual dpi of any given device. There really isn't any other way of doing it other than forcing device manufacturers to use authorised screen components (which isn't going to happen).

As for problem #1, I would look at the width:height ratio of your button and pick actual pixel dimensions based on that but larger than the 'model' 50 x 40 px. The W:H ratio is 5:4 so I'd go for a width divisible by 5 but larger than 50 perhaps 60 which is conveniently divisible by 5 and 4. This would mean creating your button image as 60 x 48 px both of which when multiplied by 0.75 for ldpi purposes give exect values (45 x 36 px).

0
votes

I don't create the assets that go into our apps (designers do), but I spend a lot of time fixing them so that they are usable across different devices.

I'd suggest something like this:

Make your layout designs (wireframes) for a mdpi 320x480 device, make your pretty designs for the highest res you're going to support. Then think about it - what assets need to stretch, minimum and maximum sizes etc to support different screens. Don't just slice the assets as they appear in your design, .9 patch them, optimise them.

Use the assets from your high res designs and let Android scale them down for you - you've laid out everything to fit on mdpi devices (don't support ldpi... urggghhhh....). A button background shouldn't be a set size, it should be a 9 patched png with min sizes - the content (text or icon) / available space / xml layout will determine the final size.

I might just be blabbering.