android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项

(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

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)   (参照引用别人的例子,害死人,这个计算公式是错的,没有用的,不能这样写的)

正确的工程应为dp = px * (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为了方便开发者对于各种分辨率机型的移植而增加了自动适配的功能  
<supports-screens  
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 文件适应多个分辨率

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、xhdpihdpimdpi、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 参考资料









多分辨率的适配问题研究

什么是多分辨率适配?
Android 多机型导致多分配率适配

常用解决方案:
1.简单 做张大图,缩放

2.完善 做大中小三种图,再按照DP做三个质量的图 根据机型、分辨率决定使用哪个图一般能在布局里自动匹配到4,5个常用的布局就不错了。

xxhdpi 144*144
xhdpi  96*96
hdpi   72*72
mdpi   48*48


通常的做法:对于Icon图片,就是做多种屏幕密度的图片尺寸,hdpi,mdpi,ldpi,xhdpi,如果横竖屏有要求的还可以针对landscape和portrait做特殊布局和图片处理,对于背景等填充型的图片,可以用.9格式的图片,,还需要根据经验,通过一些控件的属性,防止图片被拉伸变形,除此之外呢,在写布局的时候,要多用wrap_content和fill_parent等,尽量少用或者不用绝对布局.

用我之前做过的方法就是:如果你要适配N多机型的话,可以试下本来要用一张大图片的,可以用一条线来代替,在防止加载图片过多的情况下,如果你的背景比你的线宽高都大的话,线是会自动复制、自动扩充的!!!线可以是一张图片,如果你颜色值把握的好的话,可以直接写color.xml文件来实现哦...吼吼

android屏幕自适配多分辨率
如何将一个应用程序适配在不同的手机上,虽然这不算是一个技术问题,但是对于刚刚做屏幕的开发人员来说,还真不是一件多么简单的事情。

首先:你需要在AndroidManifest.xml文件的元素如下添加子元素

 
      android:normalScreens="true"android:anyDensity="true"
        android:smallScreens="true">

      名如其意,以上是为我们的屏幕设置多分辨率支持(更准确的说是适配大、中、小三种密度)。android:anyDensity="true",这一句对整个的屏幕都起着十分重要的作用,值为true,我们的应用程序当安装在不同密度的手机上时,程序会分别加载hdpi,mdpi,ldpi文件夹中的资源。
相反,如果值设置为false,即使我们在hdpi,mdpi,ldpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源,这种情况都是出现在高密度,以及低密度的手机上,比如说一部240×320像素的手机,如果设置android:anyDensity="false",Android系统会将240 x 320(低密度)转换为320×480(中密度),这样的话,应用就会在小密度手机上加载mdpi文件中的资源。


2.细心的人会发现自android2.0开始之后drawable文件被三个文件夹drawable-hdpi,drawable-mdpi,drawable-ldpi三个文件夹所取代,有些编程人员为了让应用程序默认地加载某些图片,他们会特意地去在android2.0之后的应用程序中重新创建drawable文件夹,其实这样做完全没有必要,通过第一段的分析我们得知,android:anyDensity="false",则应用会将大小密度转变成中密度,从而去加载mdpi中的资源。这里同样,当android:anyDensity="false",则应用会去加载mdpi中的资源。
总结一下:
第一:android:anyDensity="true",系统会依据屏幕密度,自动去找对应的文件夹
第二:android:anyDensity="false",
(1)               如果drawable-hdpi,drawable-mdpi,drawable-ldpi三个文件夹中有同一张图片资源的不同密度表示,那么系统会去加载drawable_mdpi文件夹中的资源
(2)               如果drawable-hpdi中有高密度图片,其它两个文件夹中没有对应图片资源,那么系统会去加载drawable-hdpi中的资源。
(3)               如果drawable-hdpi,drawable-mdpi中有图片资源,drawable-ldpi中没有对应的图片资源,那么系统会加载drawable-mdpi文件夹中的资源


3. 注意上图各种文件夹的不同表示。
drawable-hdpi 该图片即适用于横屏,也适用于竖屏
drawable-land-hdpi,当屏幕为横屏,且为高密度时,加载此文件夹中的资源
drawable-port-hdpi,当屏幕为竖屏,且为高密度时,加载此文件夹中的资源


3.有时候会根据需要在代码中动态地设置某个值,比如地图,地图的pin和地图的地址提示框的相对偏移量在不同密度的手机上是不同的。这时候可以通过以下方法求出屏幕密度:


DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int densityDpi = metric.densityDpi;   //屏幕密度DPI(120 / 160 / 240)


然后可以在代码中为这几种密度分别设置便宜量


但是这种方法最好不要使用,最好的方式是在xml文件中不同密度的手机进行分别设置。
这里地图的偏移量可以在values-hpdi,values-mdpi,values-ldpi三种文件夹中的dimens.xml文件进行设置
值得一提的是:
    40dp
    -14dp
这里的负数是完全起作用的,系统会认为它是一个负值




4. 各大手机厂商对于Android操作系统都有或多或少的改动,当然这些改动会对我们应用程序产生某些影响
  比如:
    (1)系统源代码中连接music服务的aidl文件所在包名:com.android.music 
    (2)LG则可能将该aidl文件修改所在的包(例如修改为com.android.music.player),并且修改其中的文件内容(增加一个方法,或者减少几个方法,或者修改方法名称)那么我们的应用要想在LG的手机上发布,那么我们就必须改变所要连接的aidl文件,必须跟LG厂商修改的完全一致。
2. 第二种解决方案:
2、布局的适配:
在第1点中我们已经解决了资源图片的适配问题,但是图片的大小不同势必会造成布局的差异,如果使用一个统一的布局文件,可能会造成资源图片无法完整显示在屏幕内,所以对于这种问题,解决方法是建立不同的layout文件夹,对于不同屏幕的分辨率,书写其专用的.xml文件。
多个layout文件夹在命名上有相应规则,以分辨率480x854为例,需要建立480x854像素的layout文件夹,命名:layout-854x480,有两点需要注意:①大数(854)必须在前,否则会报错;②两个数字之间的符号是小写英文字母“x”,不是乘号。系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的布局文件。

Android多分辨率适配
基本概念 

屏幕大小:以屏幕对角线的物理长度来衡量屏幕的大小 

分辨率:屏幕中所有物理像素点数。如320x480,就表示宽方向有320个像素,高方向有480个像素,整个屏幕有153,600个像素。

屏幕密度:dpi(dots perinch),即像素密度,每英寸面积上存在多少个像素。160dpi表示单位面积上有160个像素,240dpi表示单位面积上有240个像素。屏幕的密度是由分辨率和屏幕大小(物理尺寸)决定的,320x480的分辨率在3寸的屏幕上与6寸的屏幕上密度是不同的。 

dp(dip, Desity-independentpixel):密度无关像素,在Android中经常使用。android将160dp作为一个标准(即单位面积上有160个像素点时),此时1dp=1px;当将1dp放到240dp的屏幕上去时,android就会自动将1dp调整为1.5px的大小。而在美工给出的高保真一般是px,要根据给出的高保真的密度,换算到dp, 公式:

px = dp * (dpi / 160)

android将所有的密度泛化为:ldpi, mdpi, hdpi。

将屏幕大小泛化为small, normal, large, xlarge(extralarge)。 

多分辨率的适配需要在AndroidManifest.xml文件中添加子元素

    android:smallScreens="false" 
    android:normalScreens="false" 
    android:largeScreens="false" 
    android:xlargeScreens="false" 
    android:anyDensity="false" 
/>

        android:anyDensity="true",表示应用程序当安装在不同密度的手机上时,程序会分别加载hdpi,mdpi,ldpi文件夹中的资源。如果值为false,即使在hdpi,mdpi,ldpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源,应用会将大小密度转变成中密度,从而去加载mdpi中的资源。
总结如下:
第一:android:anyDensity="true",系统会依据屏幕密度,自动去找对应的文件夹
第二:android:anyDensity="false",
如果drawable-hdpi,drawable-mdpi,drawable-ldpi三个文件夹中有同一张图片资源的不同密度表示,那么系统会去加载drawable_mdpi文件夹中的资源
如果drawable-hpdi中有高密度图片,其它两个文件夹中没有对应图片资源,那么系统会去加载drawable-hdpi中的资源。
如果drawable-hdpi,drawable-mdpi中有图片资源,drawable-ldpi中没有对应的图片资源,那么系统会加载drawable-mdpi文件夹中的资源

常见文件夹命名
drawable-hdpi 该图片即适用于横屏,也适用于竖屏
drawable-land-hdpi,当屏幕为横屏,且为高密度时,加载此文件夹中的资源
drawable-port-hdpi,当屏幕为竖屏,且为高密度时,加载此文件夹中的资源

代码内动态设置值

有时候会根据需要在代码中动态地设置某个值,比如地图地址提示框相对偏移量在不同密度的手机上是不同的。这时候可以通过以下方法求出屏幕密度:
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int densityDpi = metric.densityDpi;   //屏幕密度DPI(120 / 160 / 240)
然后可以在代码中为这几种密度分别设置偏移量
但是这种方法最好不要使用,最好的方式是在xml文件中不同密度的手机进行分别设置。
这里地图的偏移量可以在values-hpdi,values-mdpi,values-ldpi三种文件夹中的dimens.xml文件进行设置。

国际化问题

    有时在xml中设置了相应的语言,但更改语言之后,UI显示仍然不起作用。这与我们在代码中引用values/string.xml中字符串的方式有关。
    错误方式:

    1. 声明全局变量 private staticString tempStr;

    2. 在onCreate方法中对该变量赋值 tempStr= context.getString(R.string.test);

    3.在更新UI的方法(非onCreate方法)中引用该变量。 textView.setText(tempStr);

    原因是由于,当修改本地语言时,onCreate不会再被执行一遍. 变量tempStr依然会使用页面刚启动时加载的默认英语。

    正确方式:

    直接进行第三步即可:textView.setText(context.getString(R.string.test));


屏幕密度,分辨率等数据获取和转换

//DisPlayMetrics对象获取
DisplayMetrics displayMetrics =getContext().getResources().getDisplayMetrics(); 
  //density比例,160dpi为1,240dpi为1.5(以160dpi为标准,240/160dpi)
displayMetrics.density;
  // 屏幕密度。160dpi,240dpi等 
displayMetrics.densityDpi;
// 字体缩放比例 

displayMetrics.scaledDensity; 
// 高上有多少个像素
displayMetrics.heightPixels;  
// 宽上有多少个像素
displayMetrics.widthPixels;  

  // 以dp值来表示的宽 
displayMetrics.xdpi;
// 以dp值来表示的高
displayMetrics.ydpi; 

以下是我对适应多屏幕的笔记,你看一下有帮助不:
对于 ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extrahigh)
4种像素密度,先以正常 mdpi(像素密度为160)为基准做(此时密度和像素1:1),
做好后,其他的图片遵循 3:4:6:8 的比例放到各自目录(4是已经做好了的);
做界面时单位用DP和SP,要使用weight权重
注意:以上只是保证不同屏幕上的同一图片看起来物理大小一样,
并不是说按比例放大缩小。
如何解决尺寸不同造成比例不协调的问题?答:用不同的布局文件:like layout-xlarge
在不同的布局里定义不同大小的长宽dp.
xlarge 屏幕至少 960dp x 720dp(注意单位,不是像素。小米手机的是:569dpX320dp,240dpi)
large 屏幕至少 640dp x 480dp
normal 屏幕至少 470dp x 320dp
small 屏幕至少 426dp x 320dp

简要概括:
1.drawable做3:4:6:8的比例来让不同密度屏幕上看起来物理大小一样
2.不同layout里定义不同的长宽使不同屏幕尺寸看起来比例协调
一个是密度,一个是尺寸


以下为一些屏幕参数术语,搞android的苦逼同行们,让多分辨率适配来的更猛烈些吧~

1、屏幕大小

屏幕实际的大小,通过测量屏幕对角线长度获得,通常用inch表示。Android将屏幕分为了4个档次:small、normal、large、xlarge。

2、屏幕分辨率
屏幕实际显示的像素数。

3、屏幕密度(PPI:Pixels per Inch)
屏幕每英寸的最大像素数(硬件层面的参数)。可通过公式进行计算:
W:横向最大像素数

H:纵向最大像素数

L:屏幕对角线长度(即前面说的屏幕大小)

4、屏幕密度(DPI:Dots per Inch)
屏幕每英寸实际显示的点数(或像素数)。属于软件参数,是手机厂商内部指定的。
App:Screen&System
Code:getResources().getDisplayMetrics().density * 160

5、密度无关的像素(DP:Density-independent pixel)
Android定义的逻辑长度单位,跟屏幕像素无关。跟像素转换的关系为:
dp = px * 160 / dpi。

6、字体大小
sp:Scale-independent Pixels。用于屏幕字体大小。类似于dp,是屏幕密度独立的单位。
在字体中,除了设置的sp会影响大小外,还有字体的类型也会对其有影响。

总结一下Android开发中适配性的问题,首先对于控件间距和大小最好使用屏幕密度dip去做,这样可以避免太大的差异
获取屏幕密度方法;
DisplayMetrics dm = new DisplayMetrics(); 
dm = getResources().getDisplayMetrics(); 
int screenWidth = dm.widthPixels; 
int screenHeight = dm.heightPixels; 
float density = dm.density; 
float xdpi = dm.xdpi; 
float ydpi = dm.ydpi;
下面是在manifest中设置app在不同分辨率时,是否支持多密度的方法。

...
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true" />

根据google的推荐,像素统一使用dip,字体统一使用sp
对于固定屏幕大小的可以在res目录下建立多个layout文件夹,文件夹名称为layout-800x480等。需要适应那种分辨率就写成什么。
注意:
          a.   较大的数字要写在前面:比如layout-854x480而不能写layout-480x854.
          b.   两个数字之前是小写字母x,而不是乘号
对于图片缩放基本两种方法;
方法一;
  private Bitmap mBitmap;
        public ScaledBitmapView(Context context, Bitmapbitmap) {
            super(context);
            mBitmap =bitmap;
        }

        @Override
        protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            finalDisplayMetrics metrics = getResources().getDisplayMetrics();
            setMeasuredDimension(
                    mBitmap.getScaledWidth(metrics),
                    mBitmap.getScaledHeight(metrics));
        }
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null);
        }
方法二;
  //对于不同分辨率屏幕缩放方法
private static int getValues_w(float value_x,int width)

return Math.round(value_x/480*width);
}

private static int getValues_h(float value_y,int height)
{
return Math.round(value_y/800*height);
}

dp与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.getResource().getDisplayMetrics().density;
  return (int)(pxValue / scale +0.5f);

}












移动设备有大有小,那么如何适应不同屏幕呢,这给我们编程人员造成了很多困惑。我也是突然想到这些问题,然后去网上搜搜相关东西,整理如下。
首先,对下面这些长度单位必须了解。
Android中的长度单位详解(dp、sp、px、in、pt、mm) http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1129/648.html
看到有很多网友不太理解dp、sp和px的区别:现在这里介绍一下dp和sp。dp也就是dip。这个和sp基本类似。如果设置表示长度、高度等属性时可以使用dp 或sp。但如果设置字体,需要使用sp。dp是与密度无关,sp除了与密度无关外,还与scale无关。如果屏幕密度为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,系统会根据屏幕密度的变化自动进行转换。
下面看一下其他单位的含义
px:(pixels)(像素):屏幕上的点,与密度相关。密度大了,单位面积上的px会比较多。表示屏幕实际的象素。例如,320*480的屏幕在横向有320个象素,在纵向有480个象素。
dip或dp(与密度无关的像素)。这个和设备硬件有关,为了支持WVGA、HVGA和QVGA 5进制空间推荐使用这个。一种基于屏幕密度的抽象单位。设置一些view的宽高可以用这个,一般情况下,在不同分辨率,都不会有缩放的感觉。如果用px的话,320px占满HVGA的宽度,到WVGA上就只能占一半不到的屏幕了,那一定不是你想要的。
sp(与刻度无关的像素)放大像素– 主要处理字体的大小。

in:表示英寸,是屏幕的物理尺寸。每英寸等于2.54厘米。例如,形容手机屏幕大小,经常说,3.2(英)寸、3.5(英)寸、4(英)寸就是指这个单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是3.2英寸,表示手机的屏幕(可视区域)对角线长度是3.2*2.54 = 8.128厘米。读者可以去量一量自己的手机屏幕,看和实际的尺寸是否一致。
mm:表示毫米,是屏幕的物理尺寸。
pt:表示一个点,是屏幕的一个物理长度,大小为1英寸的1/72。
换算公式:
px = (density/160)dp
density一般为3个常用固定值240/160/120

分别对应WVGA/HVGA/QVGA
不知道知己做的分辨率对应的density是多少可以点击AVD Manager里新建一个模拟器或者选择已有的模拟器点details就可以看到了(1.6以上包括1.6才可以查)
补充:dp跟dip是一样的,但px跟dp(dip)绝对不一样,唯一的情况只有在HVGA分辨率下才是一样,因为HVGA分辨率对应density为160,与除数一样,所以做的时候才会没感觉到差别
其次,我们在创建一个模拟器的时候,有一个选项是选择模拟器的大小,其实就是选择模拟器的屏幕大小,就是我们常说的分辨率。比如:320*48等。
Density的意思是“密度”。密度,就是说单位面积内的容量大小。
HVGA屏density=160
QVGA屏density=120
WVGA屏density=240
WQVGA屏density=120
density值表示每英寸有多少个显示点,与分辨率是两个概念。
不同density下屏幕分辨率信息:
480*800的WVGA(density=240)
density=120时 屏幕实际分辨率为240*400 (两个点对应一个分辨率)

横屏是屏幕宽度400px 或者800dip,工作区域高度211px或者480dip
竖屏时屏幕宽度240px或者480dip,工作区域高度381px或者775dip
density=160时 屏幕实际分辨率为320px*533px (3个点对应两个分辨率)
状态栏和标题栏高个25px或者25dip
横屏是屏幕宽度533px 或者800dip,工作区域高度295px或者480dip
竖屏时屏幕宽度320px或者480dip,工作区域高度508px或者775dip

density=240时 屏幕实际分辨率为480px*800px (一个点对于一个分辨率)
状态栏和标题栏高个38px或者25dip
横屏是屏幕宽度800px 或者800dip,工作区域高度442px或者480dip
竖屏时屏幕宽度480px或者480dip,工作区域高度762px或者775dip

apk的资源包中,当屏幕density=240时使用hdpi标签的资源
当屏幕density=160时,使用mdpi标签的资源
当屏幕density=120时,使用ldpi标签的资源。
不加任何标签的资源是各种分辨率情况下共用的。
布局时尽量使用单位dip,少使用px

屏幕 宽度 高度 尺寸 大小 密度

Type (Pixels) (Pixels) Range (inches) Size Group

QVGA 240 320 2.6 - 3.0 Small Low
WQVGA 240 400 3.2 - 3.5 Normal Low
FWQVGA 240 432 3.5 - 3.8 Normal Low
HVGA 320 480 3.0 - 3.5 Normal Medium
WVGA 480 800 3.3 - 4.0 Normal High
FWVGA 480 854 3.5 - 4.0 Normal High
WVGA 480 800 4.8 - 5.5 Large Medium
FWVGA 480 854 5.0 - 5.8 Large Medium

屏幕大小和密度对照表 :
duizhaobiao.jpg
下面是在manifest中设置app在不同分辨率时,是否支持多密度的方法。
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
...
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true" />
< /manifest>
screens-ranges.png
3、位图资源的缩放
当对位图资源进行缩放处理时,充分考虑设备的高度和宽度,在程序运行时获取设备的高度和宽度代码如下:
1 2 3 4
WindowManager mWMgrmWMgr = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);int width = mWMgr.getDefaultDisplay().getWidth();
int height – mWMgr.getDefaultDisplay().getHeight();
下面列举一些强烈推荐的建议:
  • 在XML布局,使用wrap_content和fill_parent来填充整个父窗口;

  • 使用FrameLayout,而不是AbsoluteLayout,减少界面布局对屏幕大小的依赖;

  • NEVER use hard-coding for pixel value, use dip (density independent pixel);

  • 根据density和resolution 为不同的设备准备合适的图片资源


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值