我们都知道 android 分为了 LDP、MDPI、HDPI、XHDP 和 XXHDPI 五类 DPI 分类,Android 4.3 还添加了 XXXHDPI 这个新的 DPI 分类。
PPI = Pixels per inch,每英寸上的像素数,即 “像素密度”
xhdpi: 2.0
hdpi: 1.5
mdpi: 1.0 (baseline)
ldpi: 0.75
drawable-ldpi、drawable-mdpi、drawable-hdpi 精度分别为低、中(android 默认)、高。
对应的图片大小为:36×36、48×48、72×72。
DENSITY | SIZE | LOCATION | RATIO | SCREEN | MARGIN |
---|---|---|---|---|---|
XXXHDPI | 192×192 | drawable-xxxhdpi | 4 | 640 DPI | 12 to 16 pixels |
XXHDPI | 144×144 | drawable-xxhdpi | 3 | 480 DPI | 8 to 12 pixels |
XHDPI | 96×96 | drawable-xhdpi | 2 | 320 DPI | 6 to 8 pixels |
HDPI | 72×72 | drawable-hdpi | 1.5 | 240 DPI | 4 to 6 pixels |
MDPI | 48×48 | drawable-mdpi | 1 | 160 DPI | 3 to 4 pixels |
MDPI | 48×48 | drawable (Cupcake) | 1 | 160 DPI | 3 to 4 pixels |
LDPI | 36×36 | drawable-ldpi | 0.75 | 120 DPI | 2 to 3 pixels |
NA | 512×512 | Google Play | NA | NA | As required |
dp 是虚拟像素,在不同的像素密度的设备上会自动适配,比如:
在 320×480 分辨率,像素密度为 160,1dp=1px
在 480×800 分辨率,像素密度为 240,1dp=1.5px
计算公式:1dp*像素密度/160 = 实际像素数
drawable- hdpi、drawable- mdpi、drawable-ldpi 的区别:
(1)drawable-hdpi 里面存放高分辨率的图片,如 WVGA (480×800),FWVGA (480×854)
(2)drawable-mdpi 里面存放中等分辨率的图片,如 HVGA (320×480)
(3)drawable-ldpi 里面存放低分辨率的图片,如 QVGA (240×320)
系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。
如今 Android 手机中屏幕像素密度最高的是 HTCOne(468DPI),DPI 级别到达 XXHDPI,而 Android 4.3 新增的 XXXHDPI 曾经接近于 640 DPI,也就是我们常说的 4K 分辨率(3840×2160)。
谷歌工程师戴安·哈克博恩(Dianne Hackborn)对此诠释称:HTC One 提供最高的像素密度,即 468DPI,可是,如今 Android 4.3 需求为新的显现设备停止筹算,即 3840×2160 分辨率的显现屏,也就是我们通常所说的 4K 分辨率,像素密度超越 600DPI,是 1080p 的两倍。
术语和概念
屏幕尺寸
屏幕的物理尺寸,以屏幕的对角线长度作为依据(比如 2.8 寸, 3.5 寸)。
简而言之, Android 把所有的屏幕尺寸简化为三大类:大,正常,和小。
程序可以针对这三种尺寸的屏幕提供三种不同的布局方案,然后系统会负责把你的布局方案以合适的方式渲染到对应的屏幕上,这个过程是不需要程序员用代码来干预的。
屏幕长宽比
屏幕的物理长度与物理宽度的比例。程序可以为制定长宽比的屏幕提供制定的素材,只需要用系统提供的资源分类符 long 和 notlong。
分辨率
屏幕上拥有的像素的总数。注意,虽然大部分情况下分辨率都被表示为“宽度×长度”,但分辨率并不意味着屏幕长宽比。在 Android 系统中,程序一般并不直接处理分辨率。
密度
以屏幕分辨率为基础,沿屏幕长宽方向排列的像素。
密度较低的屏幕,在长和宽方向都只有比较少的像素,而高密度的屏幕通常则会有很多 ——甚至会非常非常多——像素排列在同一区域。屏幕的密度是非常重要的,举个例子,长宽以像素为单位定义的界面元素(比如一个按钮),在低密度的屏幕上会 显得很大,但在高密度的屏幕上则会显得很小。
密度无关的像素( DIP )
指一个抽象意义上的像素,程序用它来定义界面元素。它作为一个与实际密度无关的单位,帮助程序员构建一个布局方案(界面元素的宽度,高度,位置)。
一个与密度无关的像素,在逻辑尺寸上,与一个位于像素密度为 160DPI 的屏幕上的像素是一致的,这也是 Android 平台所假定的默认显示设备。在运行的时候,平台会以目标屏幕的密度作为基准,“透明地”处理所 有需要的 DIP 缩放操作。要把密度无关像素转换为屏幕像素,可以用这样一个简单的公式: pixels = dips * (density / 160)。举个例子,在 DPI 为 240 的屏幕上, 1 个 DIP 等于 1.5 个物理像素。我们强烈推荐你用 DIP 来定义你程序的界面布局,因为这样可以保证你的 UI 在各种分辨率的屏幕上都可以正常显示。
为了简化程序员面在对各种分辨率时的困扰,也为了具备各种分辨率的平台都可以直接运行这些程序, Android 平台将所有的屏幕以密度和分辨率为分类方式,各自分成了三类:
·三种主要的尺寸:大,正常,小;
·三种不同的密度:高( hdpi),中( mdpi)和低( ldpi)。 【DPI 是“dot per inch”的缩写,每英寸像素数。】
如果需要的话,程序可以为各种尺寸的屏幕提供不同的资源(主要是布局),也可以为 各种密度的屏幕提供不同的资源(主要是位图)。除此以外,程序不需要针对屏幕的尺寸或者密度作出任何额外的处理。在执行的时候,平台会根据屏幕本身的尺寸 与密度特性,自动载入对应的资源,并把它们从逻辑像素( DIP,用于定义界面布局)转换成屏幕上的物理像素。
首先是几个基本概念:
1.屏幕尺寸 Screen size
即显示屏幕的实际大小,按照屏幕的对角线进行测量。
为简单起见,Android 把所有的屏幕大小分为四种尺寸:小,普通,大,超大(分别对应:small, normal, large, and extra large).
应用程序可以为这四种尺寸分别提供不同的自定义屏幕布局-平台将根据屏幕实际尺寸选择对应布局进行渲染,这种选择对于程序侧是透明的。
2.屏幕长宽比 Aspect ratio
长宽比是屏幕的物理宽度与物理高度的比例关系。应用程序可以通过使用限定的资源来为指定的长宽比提供屏幕布局资源。
3.屏幕分辨率 Resolution
在屏幕上显示的物理像素总和。需要注意的是:尽管分辨率通常用宽 x 高表示,但分辨率并不意味着具体的屏幕长宽比。
在 Andorid 系统中,应用程序不直接使用分辨率。
4.密度 Density
根据像素分辨率,在屏幕指定物理宽高范围内能显示的像素数量。
在同样的宽高区域,低密度的显示屏能显示的像素较少,而高密度的显示屏则能显示更多的像素。
屏幕密度非常重要,因为其它条件不变的情况下,一共宽高固定的 UI 组件(比如一个按钮)在在低密度的显示屏上显得很大, 而在高密度显示屏上看起来就很小。
为简单起见,Android 把所有的屏幕分辨率也分为四种尺寸:小,普通,大,超大(分别对应:small, normal, large, and extra large).
应用程序可以为这四种尺寸分别提供不同的资源-平台将透明的对资源进行缩放以适配指定的屏幕分辨率。
5.设备独立像素 Density-independent pixel (dp)
应用程序可以用来定义 UI 组件的虚拟像素单元,通过密度无关的方式来描述布局尺寸和位置。
一个设备独立像素相当于一个 160 dpi 屏幕上的物理像素。
在程序运行时,系统根据屏幕的实际密度透明的处理任何需要缩放的设备独立像素单元,设备独立像素转换成屏幕实际像素的换算很简单:pixels = dps * (density / 160).
例如在 240 dpi 的屏幕上,1 个设备独立像素等于 1.5 物理像素.为确保 UI 组件在不同的屏幕都能合适的展示,强烈建议使用设备独立像素单元来定义你的应用程序 UI。
四种屏幕尺寸分类:: small, normal, large, and xlarge
四种密度分类: ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high)
需要注意的是: xhdpi 是从 Android 2.2 (API Level 8)才开始增加的分类.
xlarge 是从 Android 2.3 (API Level 9)才开始增加的分类.
DPI 是“dot per inch”的缩写,每英寸像素数。
一般情况下的普通屏幕:ldpi 是 120,mdpi 是 160,hdpi 是 240,xhdpi 是 320。
两种获取屏幕分辨率信息的方法:
DisplayMetrics metrics = new DisplayMetrics();
Display display = activity.getWindowManager().getDefaultDisplay();
display.getMetrics(metrics);
//这里得到的像素值是设备独立像素 dp
//DisplayMetrics metrics=activity.getResources().getDisplayMetrics(); 这样获得的参数信息不正确,不要使用这种方式。
不能使用 android.content.res.Resources.getSystem().getDisplayMetrics()。这个得到的宽和高是空的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | private void initResolutionStr(Context context) { if (ApiConfig.getResolutionStr() == null || ApiConfig.getResolutionStr().equals("")) { WindowManager winMgr = (WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE); Display display = winMgr.getDefaultDisplay(); int height = display.getHeight(); int width = display.getWidth(); String resolution = height > width ? height + "x" + width : width + "x" + height; ApiConfig.setResolutionStr(resolution); // densityDpi = 120dpi is ldpi, densityDpi = 160dpi is mdpi, // densityDpi = 240dpi is hdpi, densityDpi = 320dpi is xhdpi DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int densityDpi = dm.densityDpi; ApiConfig.setDensityDpi(densityDpi); } } |
Android 上常见度量单位:
px(像素):屏幕上的点,绝对长度,与硬件相关。
in(英寸):长度单位。
mm(毫米):长度单位。
pt(磅):1/72 英寸,point。
dp(与密度无关的像素):一种基于屏幕密度的抽象单位。在每英寸 160 点的显示器上,1dp = 1px。
dip:Density-independent pixel,同 dp 相同。
sp:在 dp 的基础上,还与比例无关,个人理解为是一个矢量图形单位。
引入 dp/dip 的原因:
过去,程序员通常以像素为单位设计计算机用户界面。例如,定义一个宽度为 300 像素的表单字段,列之间的间距为 5 个像素,图标大小为 16×16 像素 等。这样处理的问题在于,如果在一个每英寸点数(dpi)更高的新显示器上运行该程序,则用户界面会显得很小。在有些情况下,用户界面可能会小到难以看清 内容。与分辨率无关的度量单位可以解决这一问题。
如何计算密度(请参照原帖:http://www.devdiv.com/thread-28610-1-1.html);
1.标准是 240*320 画在 1.5*2 平方 inch 上。那么像每平方英寸有 240*320/(1.5*2)=25600 点,也就是一平方英寸的像素点为 25600,所以 dpi 取为它的平方根 160;如果你的 dpi 是 120,那么它的密度就是 0.75.
2.密度不只是与 width 有关,还与 height 有关,所以不管 width 是 1.8 还是 1.3,它的密度都有可能是 1;比如 width 是 1.8,只要它 的 height 是 3/1.8 的话,如果 pixel 为 240*320 的话,它的密度仍旧是 1;同样如果 width 为 1.3,只要它的 height 为 3/1.3 的话,像素点为 240*320,则密度也是 1.
3.320*480/(1.5*2)得到单位平方英寸的点为 51200,所以单位平方英寸是 240*320 画在 1.5*2 屏幕的 2 倍。但是这是平方英寸啊,算密度的时候要开平方的啊,所以应该是 2 开平方,是 1.414 吧,大致密度为 1.5。
如何做到与密度无关:
如果屏幕密度为 160,这时 dp 和 sp 和 px 是一样的。1dp=1sp=1px,但如果使用 px 作单位,如果屏幕大小不变(假设还是 3.2 寸),而屏 幕密度变成了 320。那么原来 TextView 的宽度设成 160px,在密度为 320 的 3.2 寸屏幕里看要比在密度为 160 的 3.2 寸屏幕上看短了一半。但如果设置成 160dp 或 160sp 的话。系统会自动将 width 属性值设置成 320px 的。 也就是 160 * 320 / 160。其中 320 / 160 可称为密度比例因子。也就是说,如果使用 dp 和 sp,系统会根据屏幕密度的变化自动进行转换。官方文档总结的计算公式为:pixels = dps * (density /160).
参考文章:Android 上常见度量单位【xdpi、hdpi、mdpi、ldpi】解读
参考文章:【Android 笔记】各个屏幕的 logo 尺寸要求