安卓手机屏幕分辨率与dip、dp、sp的区别

来源:互联网 发布:更新驱动软件下载 编辑:程序博客网 时间:2024/05/21 14:02

以下文章知其然不知所其然,只能先看看,还有,现在的分辨率除了640x480这几种,还有720x1080这些,所有不一定就是 HVGA屏density=160;QVGA屏density=120WVGA屏density=240;WQVGA屏density=120,所以必须要知道如何计算。


android手机屏幕分辨率 及 sp dip(dp) px 区别 及高中低分辨率时处理

分辨率,是指单位长度内包含的像素点的数量,它的单位通常为像素/英寸(ppi)。以分辨率为1024×768的屏幕来说,即每一条水平线上包含有1024个像素点,共有768条线,即扫描列数为1024列,行数为768行。分辨率不仅与显示尺寸有关,还受显像管点距、视频带宽等因素的影响。

 主流分辨率:

代号分辨率代号分辨率QVGA320*240像素WQVGA400*240像素HVGA320*480像素VGA640*480像素WVGA800*480像素XGA1024*480像素

 


QVGA 即Quarter VGA。顾名思义即VGA的四分之一尺寸 
HVGA (Half-size VGA),即VGA(640*480)的一半
WVGA 即Wide VGA
WQVGA 全称:Wide Quarter Video Graphics Array

 

sp  dip  px

sp :(scaled pixels—best for text size)——带比例的像素。 主要是用于字体显示,由此根据google的建议,TextView的字体大小最好用sp做单位,而且查看TextView的源码可知Android默认使用水平作字号单位。

 

dip:(device independent pixels)——设备独立像素:这个和设备硬件有关,一般哦我们了支持WVGA、HVGA和QVGA推荐使用这个,不依赖于像素。等同于dp。

一般以HVGA(320*480)为标准,比如说一个Button控件,width为160dip,则此Button在WVGA、HVGA、QVGA、WQVGA中宽度都为屏幕的一半

 

px:px(pixels)——像素:不同的设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多。在HVGA中 1dip = 1px(慎用!)

 

总结:字体用sp,其它控件用dip(dp)

 

 高中低分辨率的处理

android开发 drawable(hdpi,mdpi,ldpi)的区别

android从2.1版本开始drawble分为drawable-mdpi、drawable-ldpi、drawable-hdpi三个,这三个主要是为了支持多分辨率。

  drawable- hdpi、drawable- mdpi、drawable-ldpi的区别:

  (1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)

  (2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)

  (3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)

  系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。

  在开发程序时为了兼容不同平台不同屏幕,建议各自文件夹根据需求均存放不同版本图片。

在项目中使用实例:

                               <ImageView

                                android:src="@drawable/zxy" //依然使用drawble的路径,而且图片名不加格式
                                android:layout_width="fill_parent" 
                                android:layout_height="fill_parent"
                                />

 

得到屏幕宽高代码:

WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE); 

Display d  = wm.getDefaultDisplay();

d.getWidth();

d.getHeight();


android 项目移植/分辨率适配与dip(dp)的使用

    博客分类: 
  • android
androiddip分辨率适配移植

如果想在不同型号手机对同一个应用做适配,如果你在xml中全部使用dp没有使用px,那么适配上依然很有可能出问题!

 

无数人存在误区,认为自己使用的都是dp,为什么在手机A上面和手机B上面看上去比例不一样,为什么在A手机上显示正好而手机B上却显示到屏幕外面

 

每次解释的都很累,所以写此blog

 

首先先明确几个概念

density值表示每英寸有多少个显示点(*)

dip/dp: device independent pixels(设备独立像素)

注意:dip与屏幕密度有关,屏幕密度与硬件有关,硬件设置不正确,有可能导致dip不能正常显示。在屏幕密度为160的显示屏上,1dip=1px

 

下面是一些分辨率信息

 

名称分辨率屏幕密度QVGA320*240120WQVGA400400*240120WQVGA432432*240120HVGA640*480160WSVGA1024*600160WXGA8001280*800160WVGA800800*480240WVGA854854*480240WXGA7201280*720320

 

下面没有特殊说明的话,屏幕的宽度都指其像素数

我们在手机A上面放了一张图片,120px宽,手机屏幕240px宽,也就是说图片的宽度占了整个屏幕的一半

如果把应用安装在手机B上,B的宽度=320px,那么我们希望图片宽度为多少呢?如果大家希望按着比例缩放,那图片宽度应该是160px,占屏幕宽度的50%

 

如果我们在xml中使用的单位为dp,下面看看如何保持这个比例:

px = (density/160)dp(density这里是(*)的意思)

我们把所期待的比例记为rate,baseDensity=160,屏幕的宽度(像素数)为x,屏幕密度为density

那么rate=((density/baseDensity)*dp)/x;

这里baseDensity是已知的=160,dp也是已知的,因为是你写的嘛。

未知的是density屏幕密度和屏幕宽度x

 

rate可以写为:

rate=(dp/baseDensity)*(density/x);

现在情况就比较明朗了,rate=K(常数)*(density/x);

如果想保持rate不变,那么需要保证density/x保持比例

 

给数学不好的同学多解释两句

想保持rate的话,必须要手机A的屏幕密度/屏幕宽度=手机B的屏幕密度/屏幕宽度

或者说手机A的屏幕密度/手机B的屏幕密度=手机A的屏幕宽度/手机B的屏幕宽度

 

同样,如果你要保持纵向也保持等比缩放,那么也同样需要保持比例。

只有这样,你的应用才能看上去是等比缩放的。

使用dp保持比例只和这些有关,和你屏幕大小半点关系都没有。

 

还有另一种方式来保持比例:就是直接使用比例方式定义组件大小

但是很有局限性,只有LinearLayout中可以使用android:layout_weight属性

 

其实很容易理解,给大家举个例子

很多人觉得,如果项目中全部使用dp,那么就可以完美移植。

我们的一个移植项目,任务是把应用从A(分辨率为WXGA720=1280*720)移植到B(分辨率WVGA800=800*480)

其中A的密度=320,B的密度为240

 

我们现在来看看A横向有多少个dp

A dp数=720/(320/160)=360

B dp数=480/(240/160)=320

 

手机A横向有360个dp,如果你的图片占用360个dp,B去哪找你多出来的40dp呢!必然它会显示在屏幕外面阿!

 

 

ps:下面是一点相关内容

下面是函数void android.util.DisplayMetrics.setToDefaults()

Java代码  收藏代码
  1. public void setToDefaults() {  
  2.     widthPixels = 0;  
  3.     heightPixels = 0;  
  4.     density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;  
  5.     densityDpi = DENSITY_DEVICE;  
  6.     scaledDensity = density;  
  7.     xdpi = DENSITY_DEVICE;  
  8.     ydpi = DENSITY_DEVICE;  
  9.     noncompatWidthPixels = 0;  
  10.     noncompatHeightPixels = 0;  
  11. }  

 

其中density变量注释如下

 

density变量注释 写道
float android.util.DisplayMetrics.density

The logical density of the display. 
This is a scaling factor for the Density Independent Pixel unit, where one DIP is one pixel on an approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), providing the baseline of the system's display. 
Thus on a 160dpi screen this density value will be 1; on a 120 dpi screen it would be .75; etc.

This value does not exactly follow the real screen size (as given by xdpi and ydpi, but rather is used to scale the size of the overall UI in steps based on gross changes in the display dpi. 
For example, a 240x320 screen will have a density of 1 even if its width is 1.8", 1.3", etc. 
However, if the screen resolution is increased to 320x480 but the screen size remained 1.5"x2" then the density would be increased (probably to 1.5).

See Also:
DENSITY_DEFAULT

可以看出这个density是个近似值,并不严格按着真实屏幕尺寸计算。



 

Android里神奇的dp

分类: android知识 3068人阅读 评论(0) 收藏 举报

看了这篇文章,我的心得有几个:

1、之所以使用dp,是为了保证控件的长度一致

2、像素一样,dpi不一样,那么长度不同

3、dp一样,dpi不一样,长度相同


所以相同的dp在不同的手机上看起来长度是一样的,而我在设置间隔的时候如果设置为具体数值的dp,那么其间隔长度也是一样的,这样比较小尺寸的手机就会出问题了


屏幕分辨率
首先要了解Android屏幕分辨率,从density来看,常见的分辨率对应关系有:
hdpi = 480x800 (如Nexus One/Nexus S)
mdpi = 320x480 (如HTC Wildfire S G13)
ldpi = 240x320 (如HTC G8)
除此之外,还有xhdpi = 960x640 (如魅族M9)
但以上只是常见的而已,实际分辨率像素数量与density无关,例如SonyEricsson X10分辨率是480x854也是hdpi,Kindlefire 的分辨率是 1024x600但实际是mdpi(large-mdpi)。另外还有各种山寨诡异的屏幕分辨率,暂且不说。

更多的参数关系可以参考:
http://developer.android.com/guide/practices/screens_support.html

什么是DP
有了以上知识之后,再看看dp。dp的意义是按照mdpi下px:dp = 1:1换算,其他分辨率按照density比例算出来(xhdpi=320,hdpi=240,mdpi=160,ldpi=120),如果不想记density值,则按照标注屏幕宽度比例换算也可以(对large-*dpi无效),也就是说:
mdpi下屏幕宽度为320px,所以就是320dp,半个屏幕自然就是160dp
hdpi下dp:px = 1:1.5 (按照屏幕宽480/320=1.5算出来),所以160dp也等于半个屏幕宽
ldpi下dp:px = 3:4 = 1:0.75 (按照240/320=0.75算出来),所以160dp也等于半个屏幕
……
其他算法也一致,所以对于常见的标准分辨率来说半个屏幕宽度就是160dp。

其他可能的问题
但仍需要考虑很多特殊情况,例如:对于像Kindlefire这种large-mdpi来说,160dp=160px,而人家实际宽度为600,就肯定是不对的。如果横屏,横屏对于480x800的hdpi的一半是400px/1.5 = 267dp,而对于480x854的hdpi的一般则是427px/1.5 = 285dp,所以会出现很多问题。

动态代码处理
所以,最为保险的方式,是在代码中,调用:

<ol class="linenums" style="list-style-position: outside; margin: 0px; padding: 0px 0px 0px 10px; border: none; font-size: 12px;"><li class="L0" style="list-style-type: decimal; list-style-position: initial; margin: 0px; padding: 0px 0px 0px 10px; border: none; line-height: 30px; color: rgb(153, 153, 153); background-color: rgb(250, 250, 250);"><span class="typ" style="color: rgb(43, 145, 175); font-weight: bold;">DisplayMetrics</span><span class="pln" style="color: rgb(0, 0, 0);"> metrics </span><span class="pun" style="color: rgb(0, 0, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 139); font-weight: bold;">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(43, 145, 175); font-weight: bold;">DisplayMetrics</span><span class="pun" style="color: rgb(0, 0, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);"></span></li><li class="L1" style="list-style-type: decimal; list-style-position: initial; margin: 0px; padding: 0px 0px 0px 10px; border: none; line-height: 30px; color: rgb(153, 153, 153); background-color: rgb(250, 250, 250);"><span class="pln" style="color: rgb(0, 0, 0);">getWindowManager</span><span class="pun" style="color: rgb(0, 0, 0);">().</span><span class="pln" style="color: rgb(0, 0, 0);">getDefaultDisplay</span><span class="pun" style="color: rgb(0, 0, 0);">().</span><span class="pln" style="color: rgb(0, 0, 0);">getMetrics</span><span class="pun" style="color: rgb(0, 0, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">metrics</span><span class="pun" style="color: rgb(0, 0, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"></span></li><li class="L2" style="list-style-type: decimal; list-style-position: initial; margin: 0px; padding: 0px 0px 0px 10px; border: none; line-height: 30px; color: rgb(153, 153, 153); background-color: rgb(250, 250, 250);"><span class="pln" style="color: rgb(0, 0, 0);"></span><span class="kwd" style="color: rgb(0, 0, 139); font-weight: bold;">int</span><span class="pln" style="color: rgb(0, 0, 0);"> screenHalfWidth </span><span class="pun" style="color: rgb(0, 0, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> metrics</span><span class="pun" style="color: rgb(0, 0, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">widthPixels </span><span class="pun" style="color: rgb(0, 0, 0);">/</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: maroon;">2</span><span class="pun" style="color: rgb(0, 0, 0);">;</span></li></ol>

然后修改view的大小:

<ol class="linenums" style="list-style-position: outside; margin: 0px; padding: 0px 0px 0px 10px; border: none; font-size: 12px;"><li class="L0" style="list-style-type: decimal; list-style-position: initial; margin: 0px; padding: 0px 0px 0px 10px; border: none; line-height: 30px; color: rgb(153, 153, 153); background-color: rgb(250, 250, 250);"><span class="pln" style="color: rgb(0, 0, 0);">view</span><span class="pun" style="color: rgb(0, 0, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">setLayoutParams</span><span class="pun" style="color: rgb(0, 0, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 139); font-weight: bold;">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(43, 145, 175); font-weight: bold;">LayoutParams</span><span class="pun" style="color: rgb(0, 0, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">screenHalfWidth</span><span class="pun" style="color: rgb(0, 0, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(43, 145, 175); font-weight: bold;">LayoutParams</span><span class="pun" style="color: rgb(0, 0, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">WRAP_CONTENT</span><span class="pun" style="color: rgb(0, 0, 0);">));</span></li></ol>

关于DisplayMetrics的使用,可以参考http://developer.android.com/reference/android/util/DisplayMetrics.html 它m里面可以获取很多与屏幕相关的内容,包括density比例,当前density等




——————————————————————————————————————————————————————————————————————

今天偶然间问了同事一个关于dp单位的问题,然后由这个问题引发的一连串的问题彻底颠覆了我关于dp的理论体系。


我那个问题是这样的:既然dp的本质是物理尺寸,为什么不用cm或者mm等传统长度单位替代?


然后他回答我dp是和像素密度无关的。。。我对这个回答不屑一顾,不过他接下来的一句话把我彻底震惊了,那句话是这样的:在你的手机上320dp就刚好满屏了,310dp就差一点点满屏。


我的手机是HTC Desire,这个理论我闻所未闻,然后马上做了个小实验,事实确实是这样,把一个TextView背景设成红色,宽度设成320dp,能看到满屏,310dp就差那么一点点。


看到这个测试结果的时候,我再一次崩溃了,我希望同事第二句话是一个美丽的错误,我无法接受这么久以来我理解的东西是错误的,可是事实是残酷的。


Android Developers关于dp的文档我看过N次,那个px和dp的转换公式我记得很清楚: px = dp * (dpi / 160),可是今天翻了源码了才发现,原来这里的dpi是归一化后的dpi,可能值只有120(low)、160(medium)、240(high)、320(xhigh)四种,而我之前理解的竟然是实际设备真实的dpi!


G7的真实dpi是252,根据我以前的理解,310dp换算成px应该是:310 * (252 / 160) = 488像素,而G7水平方向是480px,310dp在这上面绝对满屏都不止了,事实上Android系统并没有拿252作为dpi来计算,而是将G7视作hdpi设备,然后使用240dpi来计算最终像素,所以在G7上320dp刚好是:320 * (240 / 160) = 480像素,刚好满屏了,310dp确实要差一点点。


搞清楚这个问题后,我心里稍微好受点了,可是另一个问题接踵而来:
dp的本质还是物理尺寸,难道不是吗?尽管Android系统对待dp这事上,将所有设备视为四种:120(low)、160(medium)、240(high)、320(xhigh),在160dpi上,160dp就是1英寸,在240dpi上,160dp还是1英寸,120dpi和320dpi也还是1英寸,虽然他们占用的像素数不一样,但是最终显示出来的效果都是占用了屏幕上1英寸的范围。这套体系其实是非常合理的,一个宽为160dp的按钮,它在所有设备上占用的物理尺寸应该是一样大才合理,这样他们对人眼所形成的张角才一样大,观看或者阅读的感觉才一致(姑且不考虑按钮的背景是否一样细致)。这应该是Android系统引入dp概念的原因,因为手机屏幕的像素密度相差实在太大了,web那套东西已经完全不适用,你想电脑屏幕的像素密度能相差多大?


终极问题来了,现实生活中真的只有以上四种不同像素密度的设备吗?不可能。虽然所有这些设备都可以粗略地划分为low、medium、high、xhigh四种密度,可是对于划在同一范围内但具有不同像素密度的两个设备来说,同样的dp最终所占用的物理尺寸是不一样的。举个例子,G7(HTC Desire)的屏幕尺寸是3.7英寸,分辨率是480*800,像素密度是252dpi,G10(HTC Desire HD)的屏幕尺寸是4.3英寸,分辨率同为480*800,像素密度是217dpi。假设现在有一个按钮,它的宽度设为100dp,由于G7和G10同被划分为hdpi,那么在这两个设备上,这个按钮的实际宽度是:100 * (240 / 160) = 150像素,可由于这两个设备的实际像素密度是不一样的,所以真实的显示效果是:这个按钮在两个设备上的实际物理尺寸是不一样大的。而这,和Android进入dp的概念是相悖的。


你可以说对于同属于hdpi的设备而言,这个差别很小,但是在ldpi和hdpi之间这个差别就很明显了。我非常认同,可是如果在将dp转化为px的时候,不是使用归一化dpi(也就是120(low)、160(medium)、240(high)、320(xhigh)这四种),而是使用设备真实的像素密度,那么得出的像素数目虽然各不一样,但是最终显示出来的物理尺寸确实一样大的,而这种计算方法,我认为是忠于像素密度无关的理论的。


最后我还是想说,如果Android希望一个宽度为160dp的按钮在任何设备上都是1英寸大,那为什么不直接使用英寸作为度量单位呢?


如果你有好的想法,欢迎留言。



UPDATE:

今天下午在回答factar网友的问题的时候,我上面那个“终极问题”终于找到了一个合理的答案。在factar贴的网址里,我发现一句重要的话:

However, bitmap scaling can result in blurry or pixelated bitmaps, which you might notice in the above screenshots.

这句话的意思是说,图片资源在缩放的时候会造成图像模糊。按照我以上的分析,如果为了保证相同的图片资源在不同像素密度的设备上保持完全一样的尺寸大小(这完全可以做到,在dp转化成px的时候使用设备的物理像素密度参数),那图片在不同设备上的缩放因子必然不一样,而这会导致图像模糊!所以我猜想Google为了保证了图像不会模糊退了一步,让相同dp在不同设备上“差不多一样大”。


还有,这个答案也纠正了我的一个误区,现在有很多应用程序开发商为了降低安装包的大小,只使用一套hdpi资源或者一套xhdpi资源,而不提供mdpi资源或ldpi资源,希望在mdpi和ldpi设备上有系统完成缩放适应,虽然可行,但是我们不应忽视因为缩放带来的图像模糊、显示效果不佳的现象。



Android手机分辨率基础知识(DPI,DIP计算)

分类: Android平台2010-11-23 00:20 92165人阅读 评论(16) 收藏 举报
手机androiduilayoutxml

 

1.术语和概念

术语

说明

备注

Screen size(屏幕尺寸)

指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸

摩托罗拉milestone手机是3.7英寸

Aspect Ratio(宽高比率)

指的是实际的物理尺寸宽高比率,分为long和nolong

Milestone是16:9,属于long

Resolution(分辨率)

和电脑的分辨率概念一样,指手机屏幕纵、横方向像素个数

Milestone是854*480

DPI(dot per inch)

每英寸像素数,如120dpi,160dpi等,假设QVGA(320*240)分辨率的屏幕物理尺寸是(2英寸*1.5英寸),dpi=160

可以反映屏幕的清晰度,用于缩放UI的

Density(密度)

屏幕里像素值浓度,resolution/Screen size可以反映出手机密度,

 

Density-independent pixel (dip)

指的是逻辑密度计算单位,dip和具体像素值的对应公式是dip/pixel=dpi值/160,也就是px = dp * (dpi / 160)

 

 

2. DPI值计算

比如:计算WVGA(800*480)分辨率,3.7英寸的密度DPI,如图1所示

 

               图1 

Diagonal pixel表示对角线的像素值(=),DPI=933/3.7=252

 

 

 

3.手机屏幕的分类

 

3.1根据手机屏幕密度(DPI)或屏幕尺寸大小分为以下3类,如图2所示

 

 

                         

                          图2

 

3. 2手机屏幕分类和像素密度的对应关系如表1所示:

 

Low density (120), ldpi

Medium density (160), mdpi

High density (240), hdpi

Small screen

QVGA (240x320)

 

 

Normal screen

WQVGA400 (240x400)WQVGA432 (240x432)

HVGA (320x480)

WVGA800 (480x800)WVGA854 (480x854)

Large screen

 

WVGA800* (480x800)WVGA854* (480x854)

 

                                      表1

3.3手机尺寸分布情况(http://developer.android.com/resources/dashboard/screens.html)如图3所示,目前主要是以分辨率为800*480和854*480的手机用户居多


                                                        图3

   从以上的屏幕尺寸分布情况上看,其实手机只要考虑3-4.5寸之间密度为1和1.5的手机

4 UI设计

从开发角度讲,应用程序会根据3类Android手机屏幕提供3套UI布局文件,但是相应界面图标也需要提供3套,如表2所示

Icon Type

Standard Asset Sizes (in Pixels), for Generalized Screen Densities

 

Low density screen (ldpi)

Medium density screen (mdpi)

High density screen (hdpi)

Launcher

36 x 36 px

48 x 48 px

72 x 72 px

Menu

36 x 36 px

48 x 48 px

72 x 72 px

Status Bar

24 x 24 px

32 x 32 px

48 x 48 px

Tab

24 x 24 px

32 x 32 px

48 x 48 px

Dialog

24 x 24 px

32 x 32 px

48 x 48 px

List View

24 x 24 px

32 x 32 px

48 x 48 px

                                        表2

5 如何做到自适应屏幕大小呢?

1)界面布局方面 

   需要根据物理尺寸的大小准备5套布局,layout(放一些通用布局xml文件,比如界面中顶部和底部的布局,不会随着屏幕大小变化,类似windos窗口的title bar),layout-small(屏幕尺寸小于3英寸左右的布局),layout-normal(屏幕尺寸小于4.5英寸左右),layout-large(4英寸-7英寸之间),layout-xlarge(7-10英寸之间)

2)图片资源方面 

  需要根据dpi值准备5套图片资源,drawable,drawalbe-ldpi,drawable-mdpi,drawable-hdpi,drawable-xhdpi

Android有个自动匹配机制去选择对应的布局和图片资源



[我耀讨论] 【说明】分辨率和DPI,看了你就会懂的 

[复制帖子标题和链接]

686621

 

跳转到指定楼层
楼主只看该作者
灵芸   EMUI产品经理  发表于 2014-7-7 17:55:41 来自:浏览器

最新回复 2015-2-7 17:48:49

本帖最后由 灵芸 于 2014-7-7 17:55 编辑

对于熟悉终端数码产品的用户,一般在购买产品的时候会比较关注产品的尺寸、分辨率是不是高清等等,但是真正用户能体会到的屏幕高清和以下参数都有相关,你知道吗?

1、对于屏幕相关的参数概念:
In:英寸,长度单位,与像素密度无关。1in单位的物理大小在任何像素密度上都是一样的,其转换为px依赖于屏幕的像素密度;
Px:像素,是屏幕的像素点,对应的物理DPI(和后面讲到的Android DPI要区分开)是每英寸像素数,同样分辨率尺寸越大像素点越大,物理DPI值就越低,同一块屏幕的Px和物理DPI是相同的。
Dp或DIP:设备独立像素(device independent pixels),即dp(dip与dp完全相同,只是名字不同而已。在早期的Android版本里多使用dip,后来为了与sp统一就建议使用dp了),基于屏幕密度的抽象单位,不同设备不同显示屏显示效果不同和设备硬件有关,但与像素密度无关。dip/pixel = DPI/160,即1dip等价于DPI为160的设备中的1个像素点。
Sp:同dp相似,主要处理字体的大小,与像素密度无关。与dp类似,但是可以根据字体大小选项进行缩放。
为了保持性能、显示质量和兼容性,Android建议显示长度以“dp”为单位。在设计时只需参考换算成“dp”后的屏幕为设计输入,减少对屏幕尺寸及像素的依赖。“dp”是个虚拟概念,设计时只需以相同的“px”尺寸进行设计即可。

2、屏幕物理DPI的算法和举例
N:屏幕物理DPI值  
A、B:屏幕的分辨率数值
C:屏幕对角线长度
N = √(A²+B²) /C
例如:一个1280*800的8寸屏幕,A=1280、B=800、C=8, 物理N=√(1280²+800²) /8=188DPI
物理DPI只是算出来只是可建议指导软件在定义Android DPI的参考值,真实在软件实现过程中可根据此参考值做适当的选择规范DPI进行设计开发。因为分辨率、尺寸等各个厂家都是不可控的,故物理DPI是不可能统一标准大小的。Android系统是一个开放的系统,被很多终端设备厂商采用。对于不同屏幕尺寸和分辨率的支持,是Android系统的设计目标之一,所以Android在定义指导软件原则的时候则给出了Android DPI这样一个软件标准,各厂家或App只需要按照Android DPI才可能做出适用多分辨率、多厂家即可满足多种使用要求。下来我们介绍Android DPI的定义。  

3、Android DPI的参数解释
Android 3.0定义的Android DPI取值为:120DPI、160DPI,240DPI,320DPI
Android 4.2定义的Android DPI取值为:120DPI、160DPI,213DPI(TVDPI),240DPI,320DPI,480DPI
Android 4.4定义的Android DPI取值为:120DPI、160DPI,213DPI,240DPI,320DPI,400DPI480DPI,640DPI
Density
scale
1dp对应像素
1dp对应物理尺寸
MDPI(160DPI)
1.0px/dp
1.0px
1.0/160 = 1/160 in
TvDPI(213DPI)
1.33px/dp
1.33px
1.3/160=1/160 in
HDPI(240DPI)
1.5px/dp
1.5px
1.5/240 = 1/160 in
XhDPI(320DPI)
2.0px/dp
2.0px
2.0/320 = 1/160 in
1.5xhDPI(400DPI)
2.5px/dp
2.5px
2.5/400=1/160 in
xxhDPI(480DPI)
3.0px/dp
3.0px
3.0/480 = 1/160 in
xxxhDPI(640DPI)
4.0px/dp
4.0px
4.0/640 = 1/160 in

从Android的发展来看,其也是从易用性和屏幕种类发展在不断地完善自己的Android DPI的类型,满足逐渐对Android有需求的电视分辨率、2K屏等带来的更多的物理DPI屏幕需求。产品在设计之初对Android DPI影响的是当前界面的显示字体和dp定义的高度和宽度等都有考虑,定义选择任意一种DPI值都是根据其产品的定位、产品形态等等多重考虑来确定的,一切以最佳的使用体验为目标。Android DPI的确定并不会影响物理DPI值,所以高清屏仍旧还是高清屏,图片、视频的高清播放和查看完全不会受影响。
之前网友一直在探究我们的荣耀X1是不是在4.4升级版本的改大字体是不是因为改了DPI了,不再逃避肯定的说:“是!X1的4.4升级版本我们UI设计就是改了DPI值,从原来的320DPI改成了Android 4.4中最新为高清屏增加的400DPI”。中间的理由请参考【荣耀X1 Android4.4内测版 400dpi 修改说明 http://cn.club.vmall.com/thread-933163-1-1.html】 我想说的是任何大的改动都从来不是拍脑袋,是经过了多重的用户调研和数据分析之后才很慎重的下的决定,当然作为第一家采用400DPI的产品,中间的软件实现困难是经过了很多的投入的,且多次与Google沟通和交流以完善版本,且加快Goolge对400DPI的参数定义和软件支持能力。相信400DPI在X1中给大家带来的用户体验是不会让大家失望的!


 

dpi 、 dip 、分辨率、屏幕尺寸、px、density 关系以及换算(终结版)

分类: android笔记 移动应用 23453人阅读 评论(18) 收藏 举报
android

首先,说下概念(网上很多帖子几个地方都搞混了,理一下):


dip : device independent pixels ,设备无关像素。 我看很多帖子写的五花八门的,关于d的,什么display啊各种都有,既然是设备无关,我还是觉得device靠谱。

   dp就是dip

px : 像素不多说


dpi :dots per inch , 直接来说就是一英寸多少个点。常见取值 120,160,240。我一般称作像素密度,简称密度

density : 直接翻译的话貌似叫 密度。常见取值 1.5 , 1.0 。


分辨率: 横纵2个方向的像素点的数量,常见取值 480X800 ,320X480

屏幕尺寸: 屏幕对角线的长度。电脑电视同理。

     这里还涉及另外一个问题,就是屏幕比例的问题。因为只确定了对角线长,2边长度还不一定。所以有了4:3、16:9这种,这样就可以算出屏幕边长了。


重点来了,网上很多帖子直接把 density 叫做“密度”,然后就说他是像素密度,然后就说他是dpi。

在android里面,获取一个窗口的metrics,里面有这么几个值

[java] view plaincopy
  1. metrics.density;  
  2. metrics.densityDpi;  


densityDpi就是我们常说的dpi。density其实是  DPI / (160像素/英寸)  后得到的值。是不是有点奇怪,因为我带了单位。。。这个涉及到后面一个比较重要的东西,后面再说。

从上面就看得出了,DPI本身的单位也是 像素/英寸,所以density其实是没单位的,他就是一个比例值。

而dpi的单位是 像素/英寸,比较符合物理上面的密度定义,密度不都是单位度量的值么,所以我更喜欢把dpi叫像素密度,简称密度,density还是就叫density。



然后,来算算dpi。

比如一个机器,屏幕4存,分辨率480X800,他的dpi能算么。

因为不知道边长,肯定不能分开算,4是对角线长度,那直接用勾股定理算对角线像素,除以4,算出来大概是 dpi = 233 像素/英寸。

那么density就是  (233 px/inch)/(160 px/inch)=1.46 左右


顺带说下,android默认的只有3个dpi,low、medium和high,对应 120、160、240,如果没有特别设置,所有的dpi都会被算成这3个,具体可以参考下这个帖子

http://android.tgbus.com/Android/tutorial/201103/347176.shtml

其中的default就是160。



然后就该算了,我们写布局的时候,肯定还是要知道1个dp到底有多少px的。

换算公式如下:    dp = (DPI/(160像素/英寸))px  =  density px

        注意,这里都是带单位的。px是单位,dp是单位,density没单位。


为了方便,假设dpi是240 像素/英寸 , 那么density就是1.5

那么就是   dp=1.5px ,注意这是带了单位的,也就是 设备无关像素 = density 像素


那么转换数值计算的话,应该是下面这个式子

PX = density * DP

也就是 

像素 = density * 设备无关像素值  ,请注意这里有个字。

 


所以,90px 就应该是 60 dp 。不要问我为什么和公式不符了,全是单位的问题,物理老师死得早啊 


0 0
原创粉丝点击