- PPI ? Pixels per inch,每英寸上的像素数,即 “像素密度”
(1)PPI = √(长度像素数² + 宽度像素数²) / 屏幕对角线英寸数
dp:Density-independent pixels,以160PPI(hdpi)屏幕为标准,则1dp=1px,
(2)dp和px的换算公式 :
dp * ppi/160 = px。比如 1dp x 320ppi(xhdpi)/160 = 2px。
(3)sp:Scale-independent pixels,它是安卓的字体单位,以160PPI屏幕为标准,当字体大小为 100%时, 1sp=1px。
sp 与 px 的换算公式:sp = px * 160 /ppi
(4)
px = dp * ppi/160
dp = px / (ppi / 160)
px = sp * ppi/160
sp = px / (ppi / 160)
dp = sp?
density 的取值 ,见过 的 0.75,1,1.2,1.5,2,2.2
对应关系
ldpi 240 x 320 --> PPI = 120 --> icon:32 X 32 -->
mdpi 320x480 --> PPI = 160 (baseline,标准) -> icon:48 X 48 -> --> 1dp = 1px = ?
hdpi 480x800, 540x960 --> PPI = 240 --> hdpi -> icon:72 X 72 -> 1dp = 1.5px = ?
1280x 720 -> PPI = 320 --> xhdpi -> icon:96 X 96 -> 1dp = 2 px = 1sp 其他自己换算
1080x1920 -> PPI = 480 --> xxhdpi -> icon:144 X 144 -> 1dp = 2.2 px = ?
--> large/ xxxhdpi -> icon:? -> PPI =
public class DisplayUtil {
//dp 转换px
public static int dip2px(Context context, float dipValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dipValue * scale + 0.5f);
}
//px - dp
public static int px2dip(Context context, float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(pxValue / scale + 0.5f);
}
}
基于屏幕密度的抽象单位,设备无关的点,用于说明与密度无关的尺寸和位置。这些单位是相对于一个160dpi的屏幕,所有一个dp是160dpi屏幕上的一个点。
屏幕密度为160
1dip=1px
density = densityDpi /160
px = dip * (densityDpi / 160)
DisplayMetrics dm =getResources().getDisplayMetrics();
宽
int w_screen = dm.widthPixels;
高
int h_screen = dm.heightPixels;
密度
int dpi = dm.densityDpi;
Drawable Drawable Drawable
log:
ldpi 240 x 320
….. 160 mdpi( 320x480 )
……….. 240 hdpi(480x800, 540x960)
1280 x 600 1280x 800
720 x 1280, 320 xhdpi (1280x 720)
1080 x 1920 , 480 xxhdpi
drawable-nodpi
drawable-tvdpi
low=120
Medium =160
High = 240
xH =320
xxH = 480
layout layout layout
res/values/dimens.xml(default)
res/values-ldpi/dimens.xml (240x320 and nearer resolution)
res/values-mdpi/dimens.xml (320x480 and nearer resolution)
res/values-hdpi/dimens.xml (480x800, 540x960 and nearer resolution)
res/values-xhdpi/dimens.xml (720x1280 - Samsung S3, Micromax Canvas HD, etc)
res/values-xxhdpi/dimens.xml (1080x1920 - Samsung S4, HTC one, etc)
res/values-large/dimens.xml (480x800)
layout 还可以用一下方法设置大屏(包括设置平板)
layout-small
layout-large
layout-large-mdpi
layout-large-xhdpi
layout-xlarge
layout-xlarge-mdpi
layout-xlarge-xhdpi
values values values
res/values-large-mdpi/dimens.xml (600x1024)
res/values-sw600dp/dimens.xml (600x1024)
res/values-sw720dp/dimens.xml (800x1280)
res/values-xlarge-xhdpi/dimens.xml (2560x1600 - Nexus 10")
res/values-large-xhdpi/dimens.xml (1200x1920 - Nexus 7"(latest))
计算代码缘由:
android系统转换代码
// TypedValue 中的这个函数负责将dp,sp,px等维度信息转换成像素
public static int complexToDimensionPixelSize(int data,
DisplayMetrics metrics)
{
final float value = complexToFloat(data);
final float f = applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
value,
metrics); // 这个函数负责完成转换,其实现请往下看
final int res = (int)(f+0.5f); // 这里做了一个四舍五入
if (res != 0) return res;
if (value == 0) return 0;
if (value > 0) return 1;
return -1;
}
// 从这个函数的实现可以看出android系统对dp和sp处理的区别
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value; // px不需要做转换
case COMPLEX_UNIT_DIP:
return value * metrics.density; // dp转换成px
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity; // sp转换成px
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}