android 杂记2:单位 屏幕适配

争论的源头

屏幕适配
http://developer.android.com/guide/practices/screens_support.html

more-resources-types
http://developer.android.com/guide/topics/resources/more-resources.html


android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项
http://blog.csdn.net/sarsscofy/article/details/9249397
1 Android手机目前常见的分辨率


1.1 手机常见分辨率:


4:3
VGA     640*480 (Video Graphics Array)
QVGA  320*240 (Quarter VGA)
HVGA  480*320 (Half-size VGA)
SVGA  800*600 (Super VGA)


5:3
WVGA  800*480 (Wide VGA)


16:9
FWVGA 854*480 (Full Wide VGA)
HD        1920*1080 High Definition
QHD     960*540
720p    1280*720  标清
1080p  1920*1080 高清


手机:
iphone 4/4s    960*640 (3:2)
iphone5         1136*640
小米1             854*480(FWVGA)
小米2             1280*720


 


1.2 分辨率对应DPI
"HVGA    mdpi"


"WVGA   hdpi "
"FWVGA hdpi "
"QHD      hdpi "
"720P     xhdpi"
"1080P   xxhdpi "


 


2 屏幕适配的注意事项
2.1 基本设置
 


2.1.1 AndroidManifest.xml设置
在中Menifest中添加子元素


android:anyDensity="true"时,应用程序安装在不同密度的终端上时,程序会分别加载xxhdpi、xhdpi、hdpi、mdpi、ldpi文件夹中的资源。


相反,如果设为false,即使在文件夹下拥有相同资源,应用不会自动地去相应文件夹下寻找资源:


1) 如果drawable-hdpi、drawable-mdpi、drawable-ldpi三个文件夹中有同一张图片资源的不同密度表示,那么系统会去加载drawable_mdpi文件夹中的资源;


2) 如果drawable-hpdi中有高密度图片,其它两个文件夹中没有对应图片资源,那么系统会去加载drawable-hdpi中的资源,其他同理;


3) 如果drawable-hdpi,drawable-mdpi中有图片资源,drawable-ldpi中没有,系统会加载drawable-mdpi中的资源,其他同理,使用最接近的密度级别。


2.1.2 横屏竖屏目录区分
1) drawable


a) drawable-hdpi该图片即适用于横屏,也适用于竖屏;


b) drawable-land-hdpi,当屏幕为横屏,且为高密度时,加载此文件夹的资源;


c) drawable-port-hdpi,当屏幕为竖屏,且为高密度时,加载此文件夹中的资源。其他同理。


2) layout


在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,以适应对横屏竖屏自动切换。


2.2 多屏幕适配的4条黄金原则
1) 在layout文件中设置控件尺寸时应采用fill_parent、wrap_content、match_parent和dp;


具体来说,设置view的属性android:layout_width和android:layout_height的值时,wrap_content,match_parent或dp比px更好,文字大小应该使用sp来定义。


2) 在程序的代码中不要出现具体的像素值,在dimens.xml中定义;


为了使代码简单,android内部使用pix为单位表示控件的尺寸,但这是基于当前屏幕基础上的。为了适应多种屏幕,android建议开发者不要使用具体的像素来表示控件尺寸。


3) 不使用AbsoluteLayout(android1.5已废弃) ,可以使用RelativeLayout替代;


4) 对不同的屏幕提供合适大小的图片。


不同大小屏幕用不同大小的图片,low:medium:high:extra-high图片大小的比例为3:4:6:8;举例来说,对于中等密度(medium)的屏幕你的图片像素大小为48×48,那么低密度(low)屏幕的图片大小应为36×36,高(high)的为72×72,extra-high为96×96。


2.3 使用9-patch PNG图片
使用图片资源时,如果出现拉伸,因为图片处理的原因,会变形,导致界面走形。9-patch PNG图片也是一种标准的PGN图片,在原生PNG图片四周空出一个像素间隔,用来标识PNG图片中哪些部分可以拉伸、哪些不可以拉伸、背景上的边框位置等。


“上、左”定义可拉伸区域


“右、下”定义显示区域,如果用到完整填充的背景图,建议不要通过android:padding来设置边距,而是通过9-patch方式来定义。


Android SDK中提供了编辑9-Patch图片的工具,在tools目录下draw9patch.bat,能够立刻看到编辑后的拉伸效果,也可以直接用其他图片编辑工具编辑,但是看不到效果。


2.4 不同的layout
Android手机屏幕大小不一,有480x320, 640x360, 800x480……


怎样才能让Application自动适应不同的屏幕呢?


其实很简单,只需要在res目录下创建不同的layout文件夹,比如:layout-640x360、layout-800x480……所有的layout文件在编译之后都会写入R.java里,而系统会根据屏幕的大小自己选择合适的layout进行使用。


2.5 测试验证
一般使用AVD Manager创建多个不同大小的模拟器,如果条件具备,也可以直接用真机测试,这个比较靠谱。


3 参考资料
http://blog.csdn.net/guozh/article/details/8954994
http://my.eoe.cn/cainiao1/archive/2348.html(皇马船长)




res里面的drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)  
http://blog.sina.com.cn/staratsky 


(1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)
(3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)


ldpi:240x320
mdpi:320x480
hdpi:480x800、480x854
xhdpi:至少960*720
xxhdpi:1280×720




android 自适应 多屏幕支持
1、屏幕相关概念 
1.1分辨率 
是指屏幕上有横竖各有多少个像素 
1.2屏幕尺寸 
指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸 
android将屏幕大小分为四个级别(small,normal,large,and extra large)。 
1.3屏幕密度 
每英寸像素数 
手机可以有相同的分辨率,但屏幕尺寸可以不相同, 
Diagonal pixel表示对角线的像素值(=),DPI=933/3.7=252 
android将实际的屏幕密度分为四个通用尺寸(low,medium,high,and extra high) 
一般情况下的普通屏幕:ldpi是120dpi,mdpi是160dpi,hdpi是240dpi,xhdpi是320dpi 
对于屏幕来说,dpi越大,屏幕的精细度越高,屏幕看起来就越清楚 
1.4密度无关的像素(Density-independent pixel——dip) 
dip是一种虚拟的像素单位 
dip和具体像素值的对应公式是dip/pixel=dpi值/160,也就是px = dp * (dpi / 160) 
当你定义应用的布局的UI时应该使用dp单位,确保UI在不同的屏幕上正确显示。 


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


手机尺寸分布情况(http://developer.android.com/resources/dashboard/screens.html)如图所示, 


目前主要是以分辨率为800*480和854*480的手机用户居多 
从以上的屏幕尺寸分布情况上看,其实手机只要考虑3-4.5寸之间密度为1和1.5的手机 


2、android多屏幕支持机制 
Android的支持多屏幕机制即用为当前设备屏幕提供一种合适的方式来共同管理并解析应用资源。 
Android平台中支持一系列你所提供的指定大小(size-specific),指定密度(density-specific)的合适资源。 
指定大小(size-specific)的合适资源是指small, normal, large, and xlarge。 
指定密度(density-specific)的合适资源,是指ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high). 
Android有个自动匹配机制去选择对应的布局和图片资源 
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:主要放置xml配置文件或者对分辨率要求较低的图片 
drawalbe-ldpi:低分辨率的图片,如QVGA (240x320) 
drawable-mdpi:中等分辨率的图片,如HVGA (320x480) 
drawable-hdpi:高分辨率的图片,如WVGA (480x800),FWVGA (480x854) 
drawable-xhdpi:至少960dp x 720dp 
Android有个自动匹配机制去选择对应的布局和图片资源。 
  系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。 
  在开发程序时为了兼容不同平台不同屏幕,建议各自文件夹根据需求均存放不同版本图片。 


3、AndroidManifest.xml 配置 
android从1.6和更高,Google为了方便开发者对于各种分辨率机型的移植而增加了自动适配的功能 
android:largeScreens="true" 
android:normalScreens="true" 
android:smallScreens="true" 
android:anyDensity="true"/> 
3.1是否支持多种不同密度的屏幕 
android:anyDensity=["true" | "false"] 
如果android:anyDensity="true" 
指应用程序支持不同密度,会根据屏幕的分辨率自动去匹配。 
如果android:anyDensity="false" 
应用程序支持不同密度,系统自动缩放图片尺寸和这个图片的坐标。具体解释一下系统是如何自动缩放资源的。 
例如我们在hdpi,mdpi,ldpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源,这种情况都是出现在高密度,以及低密度的手机上,比如说一部240×320像素的手机, 
如果设置android:anyDensity="false",Android系统会将240 x 320(低密度)转换为 320×480(中密度),这样的话,应用就会在小密度手机上加载mdpi文件中的资源。 
3.2是否支持大屏幕 
android:largeScreens=["true" | "false"] 
如果在声明不支持的大屏幕,而这个屏幕尺寸是larger的话,系统使用尺寸为("normal")和密度为("medium)显示, 
不过会出现一层黑色的背景。 
3.3是否支持小屏幕 
android:smallScreens=["true" | "false"] 
如果在声明不支持的小屏幕,而当前屏幕尺寸是smaller的话,系统也使用尺寸为("normal")和密度为("medium)显示 
如果应用程序能在小屏幕上正确缩放(最低是small尺寸或最小宽度320dp),那就不需要用到本属性。否则,就应该为最小屏幕宽度标识符设置本属性 
来匹配应用程序所需的最小尺寸。 




4、Android提供3种方式处理屏幕自适应 
4.1预缩放的资源(基于尺寸和密度去寻找图片) 
1)如果找到相应的尺寸和密度,则利用这些图片进行无缩放显示。 
2)如果没法找到相应的尺寸,而找到密度,则认为该图片尺寸为 "medium",利用缩放显示这个图片。 
3)如果都无法匹配,则使用默认图片进行缩放显示。默认图片默认标配 "medium" (160)。 
4.2自动缩放的像素尺寸和坐标(密度兼容) 
1)如果应用程序不支持不同密度android:anyDensity="false",系统自动缩放图片尺寸和这个图片的坐标。 
2)对于预缩放的资源,当android:anyDensity="false",也不生效。 
3)android:anyDensity="false",只对密度兼容起作用,尺寸兼容没效果 
4.3兼容更大的屏幕和尺寸(尺寸兼容) 
1)对于你在声明不支持的大屏幕,而这个屏幕尺寸是normal的话,系统使用尺寸为 ("normal")和密度为("medium)显示。 
2.)对于你在声明不支持的大屏幕,而这个屏幕尺寸是larger的话,系统同样使用尺寸为("normal")和密度为("medium)显示, 
不过会出现一层黑色的背景。 


5、Android系统自动适配技巧 
Android系统采用下面两种方法来实现应用的自动适配: 
1)布局文件中定义长度的时候,最好使用wrap_content,fill_parent, 或者dp 进行描述,这样可以保证在屏幕上面展示的时候有合适的大小 
2)为不同屏幕密度的手机,提供不同的位图资源,可以使得界面清晰无缩放。 
对应bitmap 资源来说,自动的缩放有时会造成放大缩小后的图像变得模糊不清,这是就需要应用为不同屏幕密度配置提供不同的资源:为高密度的屏幕提供高清晰度的图像等。 
3)不要使用AbsoluteLayout 
4)像素单位都使用DIP,文本单位使用SP 


6、在代码中获取屏幕像素、屏幕密度 
DisplayMetrics metric = new DisplayMetrics(); 
getWindowManager().getDefaultDisplay().getMetrics(metric); 
int width = metric.widthPixels; // 屏幕宽度(像素) 
int height = metric.heightPixels; // 屏幕高度(像素) 
float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5) 
int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240) 


7、 一般多分辨率处理方法及其缺点 
7.1 图片缩放 
基于当前屏幕的精度,平台自动加载任何未经缩放的限定尺寸和精度的图片。如果图片不匹配,平台会加载默认资源并且在放大或者缩小之后可以满足当前界面的显示要求。例如,当前为高精度屏幕,平台会加载高精度资源(如HelloAndroid中drawable-hdpi 中的位图资源),如果没有,平台会将中精度资源缩放至高精度,导致图片显示不清晰。 
7.2 自动定义像素尺寸和位置 
如果程序不支持多种精度屏幕,平台会自动定义像素绝对位置和尺寸值等,这样就能保证元素能和精度160 的屏幕上一样能显示出同样尺寸的效果。例如,要让WVGA 高精度屏幕和传统的HVGA 屏幕一样显示同样尺寸的图片,当程序不支持时,系统会对程序慌称屏幕分辨率为320×480,在(10,10)到(100,100)的区域内绘制图形完成之后,系统会将图形放大到(15,15)到(150,150)的屏幕显示区域。 
7.3 兼容更大尺寸的屏幕 
当前屏幕超过程序所支持屏幕的上限时,定义supportsscreens元素,这样超出显示的基准线时,平台在此显示黑色的背景图。例如,WVGA 中精度屏幕上,如程序不支持这样的大屏幕,系统会谎称是一个320×480 的,多余的显示区域会被填充成黑色。 
7.4 采用OpenGL 动态绘制图片 
Android 底层提供了OpenGL 的接口和方法,可以动态绘制图片,但是这种方式对不熟悉计算机图形学的开发者来讲是一个很大的挑战。一般开发游戏,采用OpenGL 方式。 
7.5 多个apk 文件 
Symbian 和传统的J2ME 就是采用这种方式,为一款应用提供多个分辨率版本,用户根据自己的需求下载安装相应的可执行文件。针对每一种屏幕单独开发应用程序不失为一种好方法,但是目前Google Market 对一个应用程序多个分辨率版本的支持还不完善,开发者还是需要尽可能使用一个apk 文件适应多个分辨率。 




dpi 、 dip 、分辨率、屏幕尺寸、px、density 关系以及换算(终结版)
http://blog.csdn.net/dinko321/article/details/7992776


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


dip : device independent pixels ,设备无关像素。 我看很多帖子写的五花八门的,关于d的,什么display啊各种都有,既然是设备无关,我还是觉得device靠谱。
dp  :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,里面有这么几个值


metrics.density;  
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 。不要问我为什么和公式不符了,全是单位的问题,物理老师死得早啊 






Android上dip、dp、px、sp等单位说明
http://www.imyukin.com/?p=277


dip  device independent pixels(设备独立像素). 不同设备不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。
在android上开发的程序将会在不同分辨率的手机上运行。为了让程序外观不至于相差太大,所以引入了dip的概念。比如定义一个矩形10 x 10dip.在分辨率为160dpi的屏上,比如G1,正好是10 x 10像素。而在240 dpi的屏,则是15 x 15像素.换算公式为pixs = dips * (density/160). density就是屏的分辨率 。
这里要特别注意dip与屏幕密度有关,而屏幕密度又与具体的硬件有关,硬件设置不正确,有可能导致dip不能正常显示。在屏幕密度为160的显示屏上,1dip=1px,有时候可能你的屏幕分辨率很大如480*800,但是屏幕密度没有正确设置比如说还是160,那么这个时候凡是使用dip的都会显示异常,基本都是显示过小。
dip的换算: dip(value)=(int) (px(value)/1.5 + 0.5)
dp (与密度无关的像素):同dip是一样的。 一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp = 1px。 dip 与dp相同,多用于android/ophone示例中。
这个是最常用但也最难理解的尺寸单位。它与“像素密度”密切相关,所以首先我们解释一下什么是像素密度。假设有一部手机,屏幕的物理尺寸为1.5英寸x2英寸,屏幕分辨率为240×320,则我们可以计算出在这部手机的屏幕上,每英寸包含的像素点的数量为240/1.5=160dpi(横向)或320/2=160dpi(纵向),160dpi就是这部手机的像素密度,像素密度的单位dpi是Dots Per Inch的缩写,即每英寸像素数量。横向和纵向的这个值都是相同的,原因是大部分手机屏幕使用正方形的像素点。
不同的手机/平板可能具有不同的像素密度,例如同为4寸手机,有480×320分辨率的也有800×480分辨率的,前者的像素密度就比较低。Android系统定义了四种像素密度:低(120dpi)、中(160dpi)、高(240dpi)和超高(320dpi),它们对应的dp到px的系数分别为0.75、1、1.5和2,这个系数乘以dp长度就是像素数。例如界面上有一个长度为“100dp”的图片,那么它在240dpi的手机上实际显示为80×1.5=120px,在320dpi的手机上实际显示为80×2=160px。如果你拿这两部手机放在一起对比,会发现这个图片的物理尺寸“差不多”,这就是使用dp作为单位的效果
px  pixels(像素)  屏幕上的点,不同设备不同的显示屏显示效果相同,这是绝对像素,是多少就永远是多少不会改变。一般我们HVGA代表320×480像素,这个用的比较多。
sp  scaled pixels — best for text size (放大像素)(与刻度无关的像素):主要处理字体的大小。与dp类似,但是可以根据用户的字体大小首选项进行缩放。主要用于字体显示best for textsize。由此,根据 google 的建议,TextView 的字号最好使用 sp 做单位,而且查看TextView的源码可知 Android 默认使用 sp 作为字号单位。
使用建议:
根据google的推荐,像素统一使用dip,字体统一使用sp
为了使用户界面能够在现在和将来的显示器类型上正常显示,建议大家始终使用sp作为文字大小的单位,将dip作为其他元素的单位。当然,也可以考虑使用矢量图形,而不是用位图 。
如果 UI 能够以 sp 为单位提供设计是最好的,如果设计中没有 sp的概念,则开发人员也可以通过适当的换算取近似值。
过去,程序员通常以像素为单位设计计算机用户界面。例如,定义一个宽度为300像素的表单字段,列之间的间距为5个像素,图标大小为16×16像素 等。这样处理的问题在于,如果在一个每英寸点数(dpi)更高的新显示器上运行该程序,则用户界面会显得很小。在有些情况下,用户界面可能会小到难以看清内容。
与分辨率无关的度量单位可以解决这一问题。Android支持下列所有单位。
其他单位:(不经常用)
pt(磅) point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,非常简单易用; 在 Android 中,1pt 大概等于 2.22sp
in  inches(英寸):长度单位。
mm  millimeters(毫米):长度单位。
举个例子区别px和dip:
px就是像素,如果用px,就会用实际像素画,比个如吧,用画一条长度为240px的横线,在480宽的模拟器上看就是一半的屏宽,而在320宽的模拟器上看就是2/3的屏宽了。 而dip,就是把屏幕的高分成480分,宽分成320分。比如你做一条160dip的横线,无论你在320还480的模拟器上,都是一半屏的长度。
dip与px转换的方法:
public static int dip2px(Context context, float dipValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dipValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(pxValue / scale + 0.5f);
}




px、dp、dip、dpi、sp 等到底有什么联系区别?产生的根源和设计时的影响如何?是否屏幕密度的决定原因?
http://www.zhihu.com/question/19625584


从UI设计师的角度理解:
px(像素)是我们UI设计师在PS里使用的(不解释),同时也是手机屏幕上所显示的(也不解释)
dp是开发写layout的时候使用的尺寸单位,sp是开发写layout时关于字体的字号单位,且dp与sp总为1:1关系。


Android支持四种不同的dpi模式:ldpi mdpi hdpi xhdpi


一般地,手机分辨率与所运行的dpi模式是匹配的,例如hvga(320x480像素)的手机屏幕一般在3.5英寸左右,运行在mdpi模式下(也有例外,稍后解释)(这个是ROM控制的,app不能改变)。当运行在mdpi下时,1dp=1px:也就是说设计师在PS里定义一个item高48px,开发就会定义该item高48dp;Photoshop中14px大的字体,开发会定义为14sp。


对于一部wvga(480x800)手机(G7、N1、NS),一般是运行在hdpi模式下。当运行在hdpi模式下时,1dp=1.5px:也就是说设计师在PS里定义一个item高72px,开发就会定义该item高48dp;Photoshop中21px大的字体,开发会定义为14sp。


所以,当你的app需要适配多个dpi模式的时候(例如同时适配mdpi与hdpi),若你在wvga下做设计,你需要将你的各数值都为3的倍数,并在切图标注时将所有的数字除以3乘以2换算成dp,这样开发的同一套layout就能用在两个不同的dpi模式下,而不是写两套layout。


mdpi与hdpi是2:3的关系
mdpi与xhdpi是1:2的关系
ldpi与mdpi是3:4的关系


Galaxy Nexus 是720P屏幕,就是运行在xhdpi下的。


可以想见为什么iOS的开发者升级到 Retina Display 是多么的无痛


再补充一种例外,有些比较山寨的Pad有可能是7英寸屏幕,分辨率为wvga(480x800)运行在mdpi下,所以一部wvga手机是320x533dp,一部wvga平板是480x800dp,可以显示的内容会多很多。


我语言没有梳理的很清楚,希望你看得懂:P


px( pixel) 像素,可以简单的理解为一个点或方块,用以颜色的显示(单位),一般指印刷品或屏幕设置设备的颜色显示定义。


dip(device independent pixels)设备独立像素. 不同设备有不同的显示效果,这个和设备硬件有关,多为了支持WVGA、HVGA和QVGA 使用,不依赖像素。 


dpi(dots per inch)分辨率、解析度,每英寸像素数,多用于屏幕显示领域。类似的有ppi(Pixels per inch)多用于印刷领域。分辨率越高,则每英寸内包含的像素数越大。


sp (scaled pixels)像素(图像)缩放,在 常规情况下,尺寸大的图像(像素数量或密度高)缩放为小图像(像素数量或密度小)时清晰度不变或清晰(原图模糊时),逆向则反之。但可以通过像素插值/超样采集等技术实现相对清晰(计算轮廓边缘模拟出相似或智能分析增加清晰度、圆润感)


px(像素)和dpi(分辨率)的关系,分辨率表示每英寸内包含多少个像素,比如分辨率为72dpi时,即表明每英寸内有72个像素。在屏幕显示时像素和屏幕上的点可以是点对点或非点对点。


sp(像素缩放)和px、dpi之间没有直接换算关系,比如一个原始图像为100×100px时,把它缩放为60×60或40×80(等比例缩放或自由缩放)相关的像素排列和原始颜色会打乱,减低或保持包含颜色数量(在常规放大时不会增加包含的颜色数量),边缘颜色数量会减少。




http://stackoverflow.com/questions/14381965/image-size-drawable-hdpi-ldpi-mdpi-xhdpi


mdpi is the reference density -- that is, 1 px on an mdpi display is equal to 1 dip. The ratio for asset scaling is:


ldpi | mdpi | hdpi | xhdpi | xxhdpi | xxxhdpi
0.75 | 1    | 1.5  | 2     | 3      | 4
Although you don't really need to worry about tvdpi unless you're developing specifically for Google TV or the original Nexus 7 -- but even Google recommends simply using hdpi assets. You probably don't need to worry about xxhdpi either (although it never hurts, and at least the launcher icon should be provided at xxhdpi), and xxxhdpi is just a constant in the source code right now (no devices use it, nor do I expect any to for a while, if ever), so it's safe to ignore as well.


What this means is if you're doing a 48dip image and plan to support up to xhdpi resolution, you should start with a 96px image (144px if you want native assets for xxhdpi) and make the following images for the densities:


ldpi    | mdpi    | hdpi    | xhdpi     | xxhdpi    | xxxhdpi
36 x 36 | 48 x 48 | 72 x 72 | 96 x 96   | 144 x 144 | 192 x 192
And these should display at roughly the same size on any device, provided you've placed these in density-specific folders (e.g. drawable-xhdpi, drawable-hdpi, etc.)


For reference, the pixel densities for these are:


ldpi  | mdpi  | hdpi  | xhdpi  | xxhdpi  | xxxhdpi
120   | 160   | 240   | 320    | 480     | 640




Basically, General guidelines for designing images are:


ldpi is 0.75x dimensions of mdpi
hdpi is 1.5x dimensions of mdpi
xhdpi is 2x dimensinons of mdpi
Usually, I design mdpi images for a 320x480 screen and then multiply the dimensions as per the above rules to get images for other resolutions.


Please refer to the full explanation for a more detailed answer.


MDPI - 32px HDPI - 48px XHDPI- 64px


This Cheat Sheet might be handy for you. check the image :-)
http://i.stack.imgur.com/kV4Oh.png


low dpi is 0.75x dimensions of medium dpi
high dpi is 1.5x dimensions of medium dpi
extra high dpi is 2x dimensinons of medium dpi






http://stackoverflow.com/questions/12742792/my-xml-design-not-working-in-all-android-devices


Since you haven't posted any code, I'll just give you a brief overview of android layouts and resources.


You have to create multiple resources for your app. Android has 4 resolutions (ldpi,mdpi,hdpi and xhdpi) and 4 generalized screen sizes (small, medium, large and extra large). So you have to make 4 layouts (or 3 if you don't plan on supporting tablets, since tablets come under the extra large category) to support the screen sizes.


Here's a general guide:


put layouts for small, medium, large and extra large in your res/ folder as follows:


res/layout/sample_layout.xml             // default layout
res/layout-small/sample_layout.xml       // layout for small screen size
res/layout-large/sample_layout.xml       // layout for large screen size
res/layout-xlarge/sample_layout.xml      // layout for extra large screen size
you can also use


res/layout-land/sample_layout.xml for landscape orientation for all screen sizes or you can target landscape layouts for specific screen sizes as res/layout-medium-land/sample_layout.xml


note that all the layouts have the same name.


once you have your layouts ready, you need to take care of image resolutions also


once again in your res/ folder add images like this:


res/drawable-ldpi/sample_image.png         // low density
res/drawable-mdpi/sample_image.png         // medium density
res/drawable-hdpi/sample_image.png         // high density
res/drawable-xhdpi/sample_image.png        // extra high density
once again, all the images have the same name.


general guidelines for designing images are:


ldpi is 0.75x dimensions of mdpi
hdpi is 1.5x dimensions of mdpi
xhdpi is 2x dimensinons of mdpi
generally, I design mdpi images for a 320x480 screen and then multiply the dimensions as per the above rules to get images for other resolutions.


Android will automatically select the best combination of layout and image depending on the device. For example, for a high resolution medium size device, layout-medium and high density image will be displayed to the user.


Make sure you create emulators for all these combinations and test your app thoroughly. here's the official docs for more info:


https://developer.android.com/guide/practices/screens_support.html




理解Android中dpi和分辨率的关系,谈谈Android做成适应全部手机的UI方式
http://blog.csdn.net/ueryueryuery/article/details/20048401


最近我在做一个界面,UI给的切图是1280x720这个分辨率的,给的标注单位是px(像素)。 


我把原图自然而然地放在drawable-xhdpi中,然后开始调整布局(当时我默认1dp=2px)。把这个布局放到一个720P的电视上,发现完全变形了,奇囧无比之际,看了下电视的density,发现这货是1,这是一个mdpi的设备!!!


然后我就开始想了,720P的切图,要放在xhdpi这里,但是有的设备自身是mdpi之类的,那这个分辨率和dpi到底是什么关系?




楼主先是查了下基本的概念:


1.DPI:dots per inch,一英寸的像素数量,这个值是设备自己决定的,是写死的,当然也有厂商自己搞了个density=1.25的,我都不知道该说啥了...


Google规定的见下表:
  一英寸有多少个点儿? 我们用来density来分辨
ldpi 120dpi 0.75
mdpi 160dpi 1
hdpi 240dpi 1.5
xhdpi 320dpi 2
2.DIP(也就是我们用的dip/dp):device independent pixel,设备独立像素,我们不会直接使用px,而是使用dp,1 px = 1dp * density(由DPI)决定。


这里完全没有涉及到分辨率的问题...我觉得dpi和分辨率之间压根没有关系...


和基友讨论了好一会,终于明白了以下这两个问题:




1.为什么一个720P的设备,取mdpi里的图片,但是720P的切图要放在xhdpi里?


A: 这完全是根据主流手机来决定的,比如现在主流的是480P/hdpi的手机,那么,在做UI时,就会取720P作为xhdpi,取320P作为mdpi,取240P作为ldpi,这样一套套图就切出来了。


如果,主流的手机分辨率变成了720P/hdpi的手机,那么,在做UI时,就会取480P作为mdpi,取1080P作为xhdpi,以此类推。


至于Google是这样推荐的:取你手边最大的分辨率作为基准,做出最清晰的图(xhdpi),然后,按比例缩放,做出hdpi、mdpi和ldpi。所以从原理上,720P的切图放在哪里是可以根据设备来变换的。




2.如果720P的切图在xhdpi里,但我手头有一个mdpi/720P的设备,那怎么办呢?


(假设你的应用要支持所有奇葩的分辨率,而且你已经切好了4套图(ldpi~xhdpi)  并在layout里写了一套布局)


A: 如果你自己思考了dpi和分辨率的关系的话,你会发现,他们的关系就是没有关系...所以这个问题,我的解决办法(大家的)是,让多套dimens来帮我们解决这个问题。
  480p 600p 720p 1080p
mdpi values-sw480dp-mdpivalues-sw600dp-mdpi values-sw720dp-mdpivalues-sw1080dp-mdpi
hdpi values-sw480dp-hdpi
xhdpi values-sw480dp-xhdpi … 在你的res文件夹下,新建这些文件夹,然后再放进一个dimens.xml,用这种方法,就可以应对所有的分辨率情况了。
举例说明下:如果原图(1280x720)上有一个100x50(像素)大小的控件,那么对于一个正常的hdpi/800x480的设备来说,应该设置它的大小(dp)为:


长:(100/720*480/1.5)dp = 45dp (向上取整)
宽:(50/720*480/1.5)dp = 23dp


将这两个值写在values-sw480dp-hdpi/dimens.xml里,图的比例和原图就一样了。




那对于一个刚才我列举到的mdpi/1280x720的设备,它的大小应该是:


长:(100/720*720/1) = 100dp;


宽:(50/720*720/1) = 50dp;


将这两个值写在values-sw720dp-mdpi中,图的比例和原图就一样了。




3.不是我要黑IOS,如果IOS再出几个分辨率的话,那IOS开发者是不是都要抓狂了呢?


A: 就现在而言,我很高兴地回答你:是的! IOS布局的方式相当于Android中的绝对布局,而且它没有wrap_content和match_parent这些方式,等到IOS 10长到及腰时,我看你等做IOS开发的肿么办,哈哈。


综上,希望此帖可以帮到一些对Android布局有疑惑的同学~




android 杂记2:单位 屏幕适配_第1张图片



Android手机分辨率基础知识(DPI,DIP计算)
http://blog.csdn.net/moruite/article/details/6028547



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有个自动匹配机制去选择对应的布局和图片资源


http://www.cnblogs.com/yaozhongxiao/archive/2014/07/14/3842908.html
dpi 、 dip 、分辨率、屏幕尺寸、px、density 关系以及换算


一、基本概念

  • dip        : Density independent pixels ,设备无关像素。
  • dp        :就是dip
  • px        : 像素
  • dpi       :dots per inch , 直接来说就是一英寸多少个像素点。常见取值 120,160,240。我一般称作像素密度,简称密度
  • density : 直接翻译的话貌似叫 密度。常见取值 1.5 , 1.0 。和标准dpi的比例(160px/inc)
  • 分辨率   : 横纵2个方向的像素点的数量,常见取值 480X800 ,320X480
  • 屏幕尺寸: 屏幕对角线的长度。电脑电视同理。
  • 屏幕比例的问题。因为只确定了对角线长,2边长度还不一定。所以有了4:3、16:9这种,这样就可以算出屏幕边长了。

二、应用

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

     metrics.density; 
     metrics.densityDpi;

  densityDpi : 就是我们常说的dpi。

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

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

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

 

三、各单位间转换

1. 计算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。

2. 计算 dp 与 px

  我们写布局的时候,肯定还是要知道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 * 设备无关像素值 ,请注意这里有个值字。

 3. 为啥 标准dpi = 160

  (1)Android Design [1] 里把主流设备的 dpi 归成了四个档次,120 dpi、160 dpi、240 dpi、320 dpi

  实际开发当中,我们经常需要对这几个尺寸进行相互转换(比如先在某个分辨率下完成设计,然后缩放到其他尺寸微调后输出),一般按照 dpi 之间的比例即 2:1.5:1:0.75   来给界面中的元素来进行尺寸定义。

  也就是说如果以 160 dpi 作为基准的话,只要尺寸的 DP 是 4 的公倍数,XHDPI 下乘以 2,HDPI 下乘以 1.5,LDPI 下乘以 0.75 即可满足所有尺寸下都是整数 pixel 。

  但假设以 240 dpi 作为标准,那需要 DP 是 3 的公倍数,XHDPI 下乘以 1.333,MDPI 下乘以 0.666 ,LDPI 下除以 2

  而以 LDPI 和 XHDPI 为基准就更复杂了,所以选择 160 dpi

     (2)这个在Google的官方文档中有给出了解释,因为第一款Android设备(HTC的T-Mobile G1)是属于160dpi的。

 

四、 示例分析

1. 屏幕尺寸(screen size)

  就是我们平常讲的手机屏幕大小,是屏幕的对角线长度,一般讲的大小单位都是英寸。
  比如iPhone5S的屏幕尺寸是4英寸。Samsung Note3是5.7英寸。

  

图 1

2.像素(pixel)

  想像把屏幕放大再放大,对!看到的那一个个小点或者小方块就是像素了。

图 2

3.分辨率(Resolution)

  是指屏幕上垂直方向和水平方向上的像素个数。
  比如iPhone5S的分辨率是1136*640;Samsung Note3的分辨率是1920*1080;

图 3 

4.dpi

  是dot per inch的缩写,就是每英寸的像素数,也叫做屏幕密度。这个值越大,屏幕就越清晰。
  iPhone5S的dpi是326; Samsung Note3 的dpi是386

图 4

5.dip

  是Density independent pixel的缩写,指的是抽象意义上的像素。跟设备的屏幕密度有关系。

  它是Android里的一个单位,dip和dp是一样的。

Google的官方说明是这样的:
  Density-independent pixel (dp) 
  A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way. 
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.

  就是说在160dpi的屏幕上,1dip=1px。
  它跟屏幕密度有关,如果屏幕密度大,1dip代表的px就多,比如在320dpi的屏幕上,1dip=2px。

为什么我们在布局的时候最好要用dip,不要用px?

   是因为这个世界上存在着很多不同屏幕密度的手机,屏幕密度是什么?就是dpi,就是单位长度里的像素数量。

  想象一下,如果这些手机的尺寸一样,屏幕密度相差很大,那么是不是说一个手机水平方向上像素很少,另一个手机水平方向上像素很多?那我们画同样pix数量的时候,它显

  示的长度不就会不一样了?

  比如下面图中的两个手机,同时设置2px长度的Button,在屏幕密度较高的手机里就会显示的比较小。

  而同时设置的2dip长度的Button,在两个手机上显示的大小是一样的。

 

图 5

  所以如果你在App布局中都用的px作为单位,那么你的App跑在各个设备上就会出现奇奇怪怪的现象了。 

  来看一下emulator上的效果,我定义了两个Button,分别用px和dip做单位。

  布局文件里这样写

复制代码
复制代码

显示的界面是这样的:

  

图 6 

  getResources().getDisplayMetrics().densityDpi 就是屏幕密度。
  getResources().getDisplayMetrics().density 也可以理解为1dip相当于多少个px啦。
  上面的dpi是240,1dip=1.5px
  你看,100dip的Button是100pxButton的1.5倍长吧。



你可能感兴趣的:(Android)