Android 屏幕兼容性理解

基本概念 
屏幕大小:以对角线的长度来衡量屏幕的大小 
分辨率:屏幕上的像素个数。如320x480,就表示宽方向有320个像素,高方向有480个像素,整个屏幕有153,600个像素。 
宽高比:宽的物理长度/高的物理长度,如:6cm/8cm。而不是用像素的比值来表示,如320/480。 
屏幕密度:也可以是像素密度,即单位面积上存在多少个像素,单位是dpi。160dpi就是单位面积上有160个像素,240dpi就是单位面积上有240个像素。 
屏幕的密度是由分辨率和屏幕大小(物理尺寸)决定的,320x480的分辨率在3寸的屏幕上与6寸的屏幕上密度是不同的。 
dp(dpi):与像素无关的大小单位,将dp作为单位的可以看作是物理值。android将160dp作为一个标准(即单位面积上有160个像素点时),此时1dp=1px;当将1dp放到240dp的屏幕上去时,android就会自动将1dp调整为1.5px。 

android将所有的密度泛化为:ldpi, mdpi, hdpi。将屏幕大小泛化为small, medium, large, xlarge。

Manifest.xml中的support-screens元素 
<support-screens 
    android:smallScreens="false" 
    android:mediumScreens="false" 
    android:largeScreens="false" 
    android:xlargeScreens="false" 
    android:anyDensity="false" 
/> 

anyDensity:程序是否可在任何密度的屏幕上运行。该值主要是为使用了px作为单位的程序设计的。 
设为false时,anroid会启用density-compability特性,根据不同的屏幕密度将px值转换为合理的大小。 
设为true时,就会关闭density-compability特性。 
如果程序是以dp作为长度单位的,无论设为false, true都可以。 
xxxScreens:是否支持某屏幕。 
设为false时,表示不支持该大小的屏幕,android会启用size-compability特性,即只显示标准屏幕(normal size, mdpi)的大小。 
设为true时,表示支持该大小的屏幕,android就不会做任何处理,将程序直接显示。

Manifest.xml中的uses-sdk元素 
<uses-sdk 
    android:minSdkVersion="integer" 
    android:targetSdkVersion="integer" 
    android:maxSdkVersion="integer" 
/> 
minSdkVersion:标识程序可以在低版本的andriod系统上运行,且最低的版本是多少。默认时为1 
targetSdkVersion:该值主要是会影响support-screens元素中的属性的默认值。 
maxSdkVersion:程序最高可运行在什么版本的android系统上,该属性一般不需要设置,android 2.0.1之后,android也不会去检查该属性,只有android market才会用到

android为兼容多分辨率提供的兼容特性 
density-compatibility: 
1. dp,密度无关的单位 
2. 根据屏幕密度将px转换为合理的值 
3. pre-scale bitmap,根据当前的屏幕,从具有相应后缀的资源目录中加载资源(如:drawable-hdpi);同时,在相应后缀中无法找到指定资源时,就加载默认资源目录(drawable或drawable-mdpi)中的资源,并进行相应的缩放。 
4. auto-scale bitmap,自己创建bitmap时,android会为对其进行缩放。 
5. size-compatibility: 在support-screens的xxxScreen属性设为false,就会启用该特性。就是当程序运行在大屏幕上时,还是以正常屏幕的大小显示,其余的部分留黑。

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

Java代码 
  1. DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();  
  2.   
  3. displayMetrics.density; // density比例,160dpi的为1,240dpi的为1.5(以160dpi为标准,240/160dpi)  
  4.   
  5. displayMetrics.densityDpi; // 屏幕密度。160dpi,240dpi等  
  6. displayMetrics.scaledDensity; // 字体缩放比例  
  7.   
  8. displayMetrics.heightPixels; // 高上有多少个像素  
  9. displayMetrics.widthPixels; // 宽上有多少个像素  
  10.   
  11. displayMetrics.xdpi; // 以dp值来表示的宽  
  12. displayMetrics.ydpi; // 以dp值来表示的高  

术语和概念 
屏幕尺寸 
屏幕的物理尺寸,以屏幕的对角线长度作为依据(比如 2.8寸, 3.5寸)。 
简而言之, Android把所有的屏幕尺寸简化为三大类:大,正常,和小。 
程序可以针对这三种尺寸的屏幕提供三种不同的布局方案,然后系统会负责把你的布局方案以合适的方式渲染到对应的屏幕上,这个过程是不需要程序员用代码来干预的。

屏幕长宽比 
屏幕的物理长度与物理宽度的比例。程序可以为制定长宽比的屏幕提供制定的素材,只需要用系统提供的资源分类符long和 notlong。

分辨率
屏幕上拥有的像素的总数。注意,虽然大部分情况下分辨率都被表示为“宽度×长度”,但分辨率并不意味着屏幕长宽比。在Android系统中,程序一般并不直接处理分辨率。

密度 
以屏幕分辨率为基础,沿屏幕长宽方向排列的像素。 
密度较低的屏幕,在长和宽方向都只有比较少的像素,而高密度的屏幕通常则会有很多 ——甚至会非常非常多——像素排列在同一区域。屏幕的密度是非常重要的,举个例子,长宽以像素为单位定义的界面元素(比如一个按钮),在低密度的屏幕上会 显得很大,但在高密度的屏幕上则会显得很小。 

密度无关的像素( DIP ) 
指一个抽象意义上的像素,程序用它来定义界面元素。它作为一个与实际密度无关的单位,帮助程序员构建一个布局方案(界面元素的宽度,高度,位置)。 
一个与密度无关的像素,在逻辑尺寸上,与一个位于像素密度为 160DPI的屏幕上的像素是一致的,这也是Android平台所假定的默认显示设备。在运行的时候,平台会以目标屏幕的密度作为基准,“透明地”处理所有需要的DIP缩放操作。要把密度无关像素转换为屏幕像素,可以用这样一个简单的公式: pixels = dips * (density / 160)。举个例子,在 DPI为 240的屏幕上, 1个 DIP等于 1.5个物理像素。我们强烈推荐你用 DIP来定义你程序的界面布局,因为这样可以保证你的 UI在各种分辨率的屏幕上都可以正常显示。 

图表形式

术语

说明

备注

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

 


支持的屏幕分辨率范围 
1.5及更早版本的 Android系统,在设计的时候假定系统只会运行在一种分辨率的设备上—— HVGA( 320× 480)分辨率,尺寸为 3.2寸。由于系统只能工作在一种屏幕上,开发人员就可以针对那个屏幕来编写自己的程序,而无需去考虑程序在其他屏幕上的显示问题。 
但自从 Android 1.6以来,系统引入了对多种尺寸、多种分辨率屏幕的支持,以此满足拥有各种配置的新平台的运行需求。这就意味着开发人员在针对 Android 1.6或更新版系统开发程序的时候,需要为自己的程序在多种分辨率的屏幕上良好显示作出额外的设计。 
为了简化程序员面在对各种分辨率时的困扰,也为了具备各种分辨率的平台都可以直接运行这些程序, Android平台将所有的屏幕以密度和分辨率为分类方式,各自分成了三类: 
·三种主要的尺寸:大,正常,小; 
·三种不同的密度:高( hdpi),中( mdpi)和低( ldpi)。 
如果需要的话,程序可以为各种尺寸的屏幕提供不同的资源(主要是布局),也可以为 各种密度的屏幕提供不同的资源(主要是位图)。除此以外,程序不需要针对屏幕的尺寸或者密度作出任何额外的处理。在执行的时候,平台会根据屏幕本身的尺寸 与密度特性,自动载入对应的资源,并把它们从逻辑像素( DIP,用于定义界面布局)转换成屏幕上的物理像素。 
下表列出了 Android平台支持的屏幕中一些比较常用的型号,并显示了系统是如何把它们分类到不同的屏幕配置里的。有些屏幕分辨率并不在下面的列表上,但系统仍会把它们归入下列的某一个类型中。

 低密度( 120), ldpi 中密度( 160), mdpi 高密度( 240), hdpi 
小 屏幕 · QVGA( 240× 320),2.6~ 3.0寸   
普通 屏幕 · WQVGA( 240×400), 3.2~ 3.5寸 
· FWQVGA( 240×432), 3.5~ 3.8寸 
· HVGA( 320× 480),3.0~ 3.5寸 · WVGA( 480× 800),3.3~ 4.0寸 
· FWVGA( 480×854), 3.5~ 4.0寸 
大 屏幕  · WVGA( 480× 800),4.8~ 5.5寸 
· FWVGA( 480×854), 5.0~ 5.8寸 
 

如上表所示,所有分辨率的屏幕,都围绕在基准屏幕 周围,而基准屏幕在分类中,为“正常”尺寸,与“中”密度。之所以用 HVGA屏幕作为基准屏幕,是因为所有针对 Android 1.5或更早的程序都是针对这片屏幕所写的(因为只支持这一片),比如 T-Mobile G1。 

虽然系统支持上面 9种不同配置 的屏幕,但你并不一定需要为它们都提供各自不同的资源。系统已经提供了足够鲁棒(就是在各种恶劣环境下正常工作,对环境变化不敏感)的兼容特性,用于在各 种不同的屏幕上良好显示你的程序。这在下面的文档中会详细描述,如果你需要更多的资料,请查看“与屏幕无关的最佳实践”。

Android中图标尺寸:

AndroidManifest.xml中指定图标,名字不一定非叫icon
<application android:icon="@drawable/icon" android:label="@string/app_name">
2.0以后有三种尺寸,分别为36*36/48*48/72*72
你会看到drawable-hdpi/drawable-ldpi/drawable-mdpi不同的目录用来存储不同尺寸的图标在AndroidManifest.xml中只需要写@drawable/icon就可以,它会根据屏幕分辨率去找不同目录下的图标
hdpi里面主要放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
mdpi里面主要放中等分辨率的图片,如HVGA (320x480)
ldpi里面主要放低分辨率的图片,如QVGA (240x320)

类型 hdpi mdpi ldpi
ICON 72*72 48*48 36*36
Notification图标 48*48 32*32 24*24
标签Tab图标 48*48 32*32 24*24

icon            36*36                                                   48*48                                                      72*72

Android的icon尺寸

在运行时,程序为最佳显示效果提供了三种方法:

1.图片缩放

基于当前屏幕的 精度,平台自动加载任何未经缩放的限定尺寸和精度的图片。如果图片不匹配,平台会加载默认资源并且在放大或者缩小之后可以满足当前界面的显示要求。例如, 当前为高精度屏幕,平台会加载高精度资源(如图片),如果没有,平台会将中精度资源缩放至高精度。

2.自动定义像素尺寸和位置

如果程序不支持多种精度屏幕,平台会自动 定义像素绝对位置和尺寸值等,这样就能保证元素能和精度160的屏幕上一样能显示出同样尺寸的效果。例如,要让WVGA高精度屏幕和传统的HVGA 屏 幕一样显示同样尺寸的图片,当程序不支持时,系统会对程序慌称屏幕分辨率为320×533,在(10,10)到(100,100)的区域内绘制图形完成之 后,系统会将图形放大到(15,15)到(150,150)的屏幕显示区域。

3.兼 容更大尺寸的屏幕

当前屏幕超过程序所支持屏幕的上限时,定义supports- screens元素,这样超出显示的基准线时,平台在此显示黑色的背景图。例如,WVGA 中精度屏幕上,如程序不支持这样的大屏幕,系统会谎 称是一个320×480的,多余的显示区域会被填充成黑色。

但为了达到最佳的显示效 果,最好的方法还是设计多套图片。那就有必要对于所有的屏幕依据精度值进行分级(高中低),之后再设计三套icon:

先为主流的中精度屏 幕(HVGA)设计一套icon,确定图片的像素尺寸。
为高精度屏幕将图片放大到150%,为低精度屏幕将图片缩小至75%。
将这三套资 源放置到程序的三个文件夹下 :res/drawable-mdpi/ 、res/drawable-hdpi/、 res/drawable- ldpi/。程序在运行时,平台会根据屏幕的精度调取合适的icon。

Android程序对不同手机分辨率自适应总结:

各种Android操作系统的手机简直就是琳琅满目,屏幕分辨率的差异可想而知。目前比较主流的有WVGA=800x480,HVGA=480x320,另外的还有QVGA=320x240。当然还有魅族M9的DVGA=960x640,还有蛋疼的摩托罗拉的FWVGA=854x480。

其实,在你layout的xml文件中,编写的时候是不是用了许多的padding呢?如果是,那你就蛋疼了。因为这样的布局永远是无法适应所有手机屏幕的。

正确的做法应该是使用的是weight属性。将你控件的layout中的width、height设置为fill-parent,不要使用wrap——content。因为wrap-content的大小是不固定的。而weight(权重)这个属性很好的解决了这个问题。

当包裹在控件外面的Layout的width、height属性都设置为fill-parent时,可以利用weight的反比特性。即如果控件A设置weight为5,控件B设置weight为7,那么A所占的空间为5/(5+7),B所占的空间为7/(5+7)。这样的反比属性对任何分辨率下的手机都是合适的。

当然,字体就不行了。那怎么保证字体能够跟布局一样能够自适应呢? 呵呵,很简单,就是在你的res文件夹中创建一个文件夹,叫做values-320x240。其中320x240是你手机屏幕的分辨率,根据你手机屏幕的情况做不同的命名,例如values- 800x480。在该文件夹下创建一个dimens.xml文件,定义各种字体的大小。那么系统就会自动根据你手机屏幕的分辨率去调用x相应的文件夹。

另外,值得提醒的是,记得在你默认的values文件下的dimens.xml文件中也要写上相应的字体大小哦,因为当系统无法认识你手机屏幕大小的时候,它会自动去找你默认文件中的东西,没有写的话程序会崩溃

以下是结论:
    屏幕分辨率:1024x600
    density:1(160)
    文件夹:values-mdpi-1024x600

    屏幕分辨率:1024x600
    density:1.5(240)
    文件夹:values-hdpi-683x400  由1024/1.5  600/1.5得到,需要四舍五入。

    屏幕分辨率:800x480
    density:1(160)
    文件夹:values-mdpi-800x480

    屏幕分辨率:800x480
    density:1.5(240)
    文件夹:values-hdpi-533x320  由800/1.5  480/1.5得到,需要四舍五入。

以此类推
    一般情况下需要创建出values 、values-mdpi 、 values-hdpi文件夹,以备在一些没有规定的尺寸屏幕上找不到资源的情况。

    然后在里面使用不同的dimens文件,Layout中不要使用显示的数字,所有的尺寸定义全都援引dimens里面的内容。

    这样能够保证深度UI定制的情况

    另外在工程的default.properties中如果split.density=false,则分辨率适配的时候文件夹命名不需要与scale相除

例:
  屏幕分辨率:800x480
  density:1.5(240)
  文件夹:values-hdpi-800x480

关于dimens 

  位置:res\values
    单位:px   Pixel 以画面的像素为单位;
         in     Inches以画面的多少英寸为单位;
         mm  Millimeter以画面的多少毫米为单位;
         pt     Points 一点为1/72英寸;
         dp或dip  Density-indepentdent 为160dpi屏幕的一个pixel;
         ap Scale-independent Pixels 随屏幕尺寸改变的一个pixel;

假设需要适应320x240,480x320分辨率。在res目录下新建文件夹values-320x240, values-480x320。然 后在文件夹 values ,values-320x240 和  values-480x320 下新建xml文件dimens.xml,该xml文件内容如下:

1
2
3
4
<? xml  version = "1.0"  encoding = "utf-8" ?>
< resources >
     < dimen  name = "btnTextSize" >14dip</ dimen >
</ resources >

针对不同的分辨率,btnTextSize的值不同。在布局文件中,用下面的方式引用该值:

1
2
3
4
< TextView  android:layout_width = "fill_parent"
     android:layout_height = "wrap_content"  android:gravity = "center"
     android:id = "@+id/lblSet"  style = "@style/btntext"  android:textSize = "@dimen/btnTextSize" >
</ TextView >

通过这种方法,可以方便设置在不同分辨率下,字体的大小了。当然,不仅仅字体大小,宽和高等其他的一些属性,也可以通过类似的方式来设置layout中设置图片自适应大小,并且设置最大宽高,当图片的宽高大于设置的最大值时,宽高值为设置的最大值。

[xhtml]  view plain copy print ?
  1. <ImageView android:id="@+id/image_view"    
  2.       android:layout_width="wrap_content"  
  3.       android:layout_height="wrap_content"  
  4.       android:adjustViewBounds="true"  
  5.       android:maxWidth="42dp"  
  6.       android:maxHeight="42dp"  
  7.       android:scaleType="fitCenter"  
  8.       android:layout_marginLeft="3dp"  
  9.       android:src="@drawable/icon"  
  10.       />  

 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值