0
votes

Expected Result

I have a some UI widgets whose dimensions are design for iPhone 4 Retina device. The unit is in pixels, e.g. a button with 30 pixels wide by 30 pixels high. I wanna copy the design style into Android devices, say the previous 30 by 30 button, takes 30/640 = 4.6875% of the screen width in iPhone 4 Retina and 30/960 = 9.375% of the screen height, then I expect it also takes 4.6875% of the Android device screen width, 9.375% of the screen height.

Problem

Don't know the size scale factor of iPhone 4 Retina device which is used in the following code.

Code

/**
 * Change dip value to pixel value using density of current device
 */
public static int dip2px(Context context, float dpValue) {
    final float scale = context.getResources().getDisplayMetrics().density;
    Log.d("ch", "density of current device : " + scale);
    return (int) (dpValue * scale + 0.5f);
}

/**
 * Change pixel value to dip value using density of current device
 */
public static int px2dip(Context context, float pxValue) {
    final float scale = context.getResources().getDisplayMetrics().density;
Log.d("congliu", "density of current device : " + scale);
    return (int) (pxValue / scale + 0.5f);
}

Reference

iPhone 4 Retina

ppi : 326

resolution : 640 by 960 pixels

size scale factor : Unknown

Samsung Galaxy S

ppi : 233

resolution : 480 by 800 pixels

size scale factor : 1.5

Samsung Galaxy Note

ppi : 285

resolution : 800 by 1280 pixels

size scale factor : 2.0

2
Expecting identical width/height percentages on Android devices implies you're assuming all devices have the same screen aspect ratio. That's not the case, so there isn't going to be a one-on-one mapping. Anyways, 326 ppi would mean xhdpi, or the same 2.0 scale factor as for the Note (with mdpi as baseline). Also read: Supporting Multiple Screens.MH.

2 Answers

1
votes

There are several perspectives you should consider. But i just following a simple way:

px -> dp

My image resources are located in xhdpi folder, using images for retina iphone.

Suppose you have a pixel value in ios, for example, 10,

if you want to get pixel value for your android device:

DisplayMetrics dm = new DisplayMetrics();
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(dm);

SCREEN_DENSITY = dm.density;
SCREEN_WIDTH_DP = (int) (SCREEN_WIDTH_PIXELS / dm.density);

public static int getScaledWidthPixelsByDP(int desingDP) {
    double v = desingDP / 320f * SCREEN_WIDTH_PIXELS;
    return (int) v;
}
0
votes

Assuming that iPhone 4 Retina version's size scale factor is 2.0 (xhdpi in Android), I did a very simple workaround by just give those pixels value a half of it with dp unit. So 30px by 30px button turns to be 15dp by 15dp in xml file. Looks good and works on Google Nexus, Samsung Galaxy S, S2, S4, Note, Note2. The dp2px and px2dp methods are not used.