Working with hardcoded pixels and multiple resolutions in Android OS

One of the mobile apps I’m working on for Android OS draws some views manually on the screen. The drawing part is relatively easy but dealing with multiple different resolutions is a little trickier.

Android devices come in a variety of pixel densities. This creates a problem when drawing images because the physical size of 10 pixels in one density isn’t the same in another. Thankfully, both SDK’s offer ways to calculate a normalized size so that side-by-side they would appear roughly the same when you look at them.

To keep things the same across different densities, you should specify all your measurements in density independent pixels (dip). For example, to set layout margins in XML, you should do something like this using dip values:

<TextView
	android:layout_height="fill_parent"
	android:layout_width="fill_parent"
	android:layout_marginLeft="20dip"
	android:layout_marginTop="85dip"
	android:layout_marginRight="10dip"
	android:layout_marginBottom="50dip"
/>

That’s easy enough in XML but in code, you need to get the density and do a little math:

LayoutParams layout = new RelativeLayout.LayoutParams(
	RelativeLayout.LayoutParams.FILL_PARENT,
	RelativeLayout.LayoutParams.FILL_PARENT);

// Convert the dips to pixels
final float scale = getContext().getResources().getDisplayMetrics().density;
layout.setMargins(
	(int)(20.0f * scale + 0.5f), 
	(int)(85.0f * scale + 0.5f), 
	(int)(10.0f * scale + 0.5f), 
	(int)(50.0f * scale + 0.5f)
);

(I added 0.5f to avoid rounding errors when the value is converted to full pixels.)

Now 10dip is roughly the same physical size in various android device densities.

For more on Android see Supporting Multiple Screens