关于android的dp和px的关系是我刚开始学习android的第一个知识点,不知不觉学安卓也有一年了,但是偶然间我发现我理解的dp和px的关系一直是错的,真的是有一点搞笑,今天特意写一篇博客纪念一下这个我理解错一年的知识点。
dp和px之间又有一个dpi作为桥梁,我们分别看看这三个属性:
px:
像素点,比如1080*1920的屏幕,就是宽1080个像素点和高1920个像素点。
ppi:
像素密度,这个概念挺好理解的就是屏幕每英寸的像素数量,关于他的计算方法(以1080 * 1920的5英寸屏幕为例):屏幕的对角线像素数/屏幕的尺寸 √(1080 * 1080+1920 * 1920)/5=441ppi。这也就意味着即使是相同分辨率的手机尺寸不同ppi也会改变。
dpi:
dpi和ppi很容易搞混,其实他们是完全不同的两个东西,ppi有专门的公式计算,但是dpi没有,它往往是写在系统出厂配置文件的一个固定值,Android在规范中规定了不同的分辨率对应的dpi值,一般有120、160、240、320、480几个。比如,几部相同分辨率不同尺寸的手机的ppi可能分别是是430,440,450,那么在Android系统中,可能dpi会全部指定为480,该分辨率下1dp=3px。
dp(也叫dip)设备无关像素。
关于dp的官方叙述为当屏幕每英寸有160个像素时(也就是160dpi),dp与px等价的,1dp=1px。那么当屏幕为240dpi时,1dp=(240/160)px=1.5px。也就是说dp和px的换算在于dpi这个值,计算的公式为:1dp=(屏幕的dpi/160)px。
关于dp和px的概念就这么多,还是很简单的(我这是在打脸吗),下面讲一下衍生出的几个问题:
1.系统根据dp计算像素值的过程
px = dp(dpi/160),这个不难理解,如果一个20dp的Button,在dpi为480的设备占的像素值就是20(480/160)=60px,这个有一点要注意,px的计算完全依照dpi这个参数,而不同尺寸和分辨率的机型的dpi可能相同,这就会造成显示差异。
2.手机屏幕dp最大值是多少?
这个是根据手机的像素数和dpi计算得到,公式:dp=px/(dpi/160) 。也就是px = dp × (dpi / 160)
例如一个1080*1920的手机,他的宽度有1080个像素点,dpi为480,根据公式可得:1080/(480/160)=360dp
同理长度:1920/(440/160)=640dp
3.dp和px的互相转换?
这里会用到我们在代码中可以获取到的一个值:手机密度Density,其实他就是手机的像素密度与基准的比值。 即像素密度为160时Density为1,可以通过下面的方法获取这个值:
float scale = context.getResources().getDisplayMetrics().density;
dp值转换为px值得方法为:
假设手机密度 :density = x,dp的值为y
由1dp = density px
可知ydp = yx px
所以结果为yx
px值转换为dp值得方法为:
假设手机密度 :density = x,px的值为y
由1px = 1/density dp
可知 ypx = y/x dp
所以结果为y/x
public class DensityUtil { /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * 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); }
}
至于为什么要加0.5f?
因为在java中,强制转换符把float转换为int时,是直接丢掉小数部分的,加0.5f起到了四舍五入的作用,可以减小误差。
二 不同屏幕密度下的换算
在Android中,dp
(密度无关像素)和px
(像素)是常用的单位,它们之间的换算关系为:px = dp × (dpi / 160)
,其中dpi
是屏幕的像素密度。以下是具体介绍:
基本概念
dp
(密度无关像素):也叫dip
,是一种与设备屏幕密度无关的抽象单位。使用dp
作为单位可以确保在不同屏幕密度的设备上,界面元素的视觉大小保持一致。px
(像素):是屏幕上实际的物理像素点。不同设备的屏幕像素密度不同,相同数量的px
在不同屏幕上的实际显示大小可能会不同。
换算关系说明
- 公式中的
160dpi
是Android系统定义的基准屏幕密度。当屏幕密度为160dpi
时,1dp
等于1px
。如果屏幕密度高于160dpi
,那么1dp
对应的px
数量就会大于1
;反之,如果屏幕密度低于160dpi
,1dp
对应的px
数量就会小于1
。
不同屏幕密度下的换算示例
- 低密度屏幕(ldpi,120dpi):根据换算公式,
1dp = 120 / 160 = 0.75px
。例如,一个宽度为100dp
的视图,在低密度屏幕上的宽度为100 × 0.75 = 75px
。 - 中密度屏幕(mdpi,160dpi):这是Android系统的基准密度,此时
1dp = 1px
。所以一个50dp
宽的视图,在中密度屏幕上的宽度就是50px
。 - 高密度屏幕(hdpi,240dpi):按照公式计算,
1dp = 240 / 160 = 1.5px
。若有一个80dp
宽的视图,在高密度屏幕上的宽度为80 × 1.5 = 120px
。 - 超高密度屏幕(xhdpi,320dpi):通过换算可得
1dp = 320 / 160 = 2px
。比如一个60dp
宽的视图,在超高密度屏幕上的宽度为60 × 2 = 120px
。 - 超超高密度屏幕(xxhdpi,480dpi):经计算
1dp = 480 / 160 = 3px
。假设视图宽度为40dp
,在超超高密度屏幕上的宽度为40 × 3 = 120px
。
在代码中进行换算
在Android代码中,可以通过以下方法实现dp
和px
的相互转换:
import android.content.Context;public class DensityUtil {// 将dp转换为pxpublic static int dp2px(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}// 将px转换为dppublic static int px2dp(Context context, float pxValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (pxValue / scale + 0.5f);}
}
上述代码中,dp2px
方法将dp
值转换为px
值,px2dp
方法则将px
值转换为dp
值。在实际使用时,传入当前的Context
对象和需要转换的值即可。例如:
// dp转px
int pxValue = DensityUtil.dp2px(context, 100);// px转dp
int dpValue = DensityUtil.px2dp(context, 200);
三 设置模拟器
在开发适用于宽高为 5120 * 1600 的车载中控屏的 Android App 时,设置 Android 模拟器的宽高需要综合多方面因素考量,以下为介绍不同情况的设置建议:
直接模拟真实尺寸
若要精确模拟车载中控屏的实际显示效果,可将模拟器的宽高直接设置为 5120 * 1600。这种设置的优点是能最大程度还原真实的显示场景,让看到 App 在该屏幕上的实际布局和视觉效果。不过,其缺点也较为明显,由于分辨率过高,可能会对开发机器的性能造成较大压力,导致模拟器运行缓慢甚至卡顿。
根据设计稿尺寸模拟
- 等比例缩放:如果设计稿是按照车载中控屏的实际尺寸设计的,可以对其进行等比例缩放,选择一个既能保证模拟效果又不会对性能造成过大压力的尺寸。例如,将宽高按比例缩小为 2560 * 800 ,这样既保持了与实际屏幕相同的宽高比,又降低了分辨率,使模拟器运行更加流畅。
- 常见设计尺寸:在设计过程中,也可以参考一些常见的设计尺寸。如 1920 * 1080 这种全高清分辨率,是较为通用的设计尺寸,很多设计工具和素材资源都是基于此尺寸进行设计的。使用该尺寸可以方便获取和适配设计资源,同时也能在一定程度上模拟出 App 在大屏幕上的布局和显示效果。
考虑不同屏幕密度
除了宽高尺寸,还需要考虑屏幕密度(dpi)。屏幕密度会影响界面元素的实际显示大小,不同的屏幕密度可能会导致布局出现差异。在设置模拟器时,要根据车载中控屏的实际屏幕密度来设置模拟器的密度,以确保 App 在模拟器上的显示效果与实际设备一致。
以下是在 Android Studio 中设置模拟器的步骤:
- 打开 Android Studio,点击菜单栏中的 “Tools” -> “AVD Manager”。
- 在 AVD Manager 中,点击 “Create Virtual Device”。
- 选择合适的设备类型,如 “Tablet” 或自定义设备。
- 在 “System Image” 中选择合适的 Android 版本。
- 在 “Configure Device” 页面,设置 “Screen Resolution” 为需要的宽高尺寸,同时设置 “Density” 为合适的屏幕密度。
- 点击 “Finish” 完成模拟器的创建。