Android屏幕适配

由于Android的开源,各路厂商都纷纷跟进开发Android设备,这导致了Android的产生了比较严重的碎片化,今天主要说一下Android的屏幕适配。
一、首先普及几个概念
1、屏幕尺寸:指的是屏幕对角线长度,单位为英寸(inch)。很明显这是一个长度单位,我们其实大部分人会把屏幕尺寸认为是屏幕的可视面积,这是不对的。
简单来说,同样的尺寸,宽高比不同会导致手机的屏幕面积的不同。就像前几年厂商鼓吹的PC屏幕16:9的比例的代替16:10,其中一方面就是因为屏幕切割时16:9比16:10的利用率更高,
也就是同样的玻璃面板可以切割出更多的屏幕。而这放到手机屏幕上也是适用的。
2、px:指的是屏幕的物理像素点,我们说的720P,1080P指的就是这个。
3、ppi/dpi:即每英寸所拥有的像素数目(pixels per inch)。所表示的是每英寸所拥有的像素(pixel)数目。计算公式表达为 PPI=√(X²+Y²)/ Z (X:长度像素数;Y:宽度像素数;Z:屏幕尺寸)。计算公式如下图。
4、desnity:Android里面规定的屏幕逻辑密度。把160dpi定义为基准密度,值为1。这里需要注意,密度是有分辨率和屏幕尺寸两个因素决定的,同样的分辨率在手机和pad上对应的密度肯定是不一样的。
5、dp/dip:屏幕无关像素,指的是自适应屏幕密度的像素,这里应注意不要和dpi混淆。用于指定控件宽高。我们开发时都用这个单位。
6、sp:刻度无关像素:单位sp,指的是自适应字体的像素,用于指定文字大小。Android中sp受系统设置的字体大小影响,与dp有一定的换算关系,默认情况下sp和dp对px的换算关系是一样的,也就是1sp=1dp
但是当我们修改系统设置,字体大小时,这个sp与dp的就有一个系数的换算关系。具体的系数跟各个厂商有关系。DisplayMetrics.scaledDensity这个字段标示了换算的系数。

二、Android中的定义
1、Android为屏幕DPI定义好了几个常量。

public static final int DENSITY_LOW = 120;      desnity = 0.75     240*320
public static final int DENSITY_MEDIUM = 160;   desnity = 1        320*480
public static final int DENSITY_HIGH = 240;     desnity = 1.5    480*800(HD)/480*854(HD)/540*960(QHD)
public static final int DENSITY_XHIGH = 320;    desnity = 2        720*1280(720P)
public static final int DENSITY_XXHIGH = 480;   desnity = 3        1080*1920(1080P)
public static final int DENSITY_XXXHIGH = 640;  desnity = 4        1440*2560(2K/qHD)

正常情况下,屏幕的宽高比会和分辨率的宽高比并不一致,也就是说一块屏幕的横向密度和竖向密度其实是不一样的,
这里拿屏幕尺寸5英寸,宽高4.36" × 2.45" 的一块标准720P(720*1280)分辨率的屏幕做例子,通过计算我们发现这块屏幕整体的密度为293.72 DPI,而竖直的密度为293.878 DPI,水平的密度为293.578 DPI,这三个密度跟Android定义的都不等,Android的做法是为手机强行指定一个密度,也就是最靠近的320,这个密度写在Android的配置文件build.prop中。在使用时,直接读取这个密度做缩放。

一般刚从芯片厂商拿到的工程机源码中都是没有这个配置的,所以第一版rom显示起来往往千奇百怪,我们现在拿到的量产机则都是手机厂商调教好的,有探索精神的同学可以试着root后改一下这个配置文件看一下,改完后屏幕显示比例会改变,当然也可能就开不开机了,这跟每个厂商的设置有关系。


三、Android适配的原则。

   Andorid发展到现在,从早期Android各种奇葩宽高比的手机,现在又有虚拟按键的加入,再有各种厂商二次优化(比如魅族MX3 1920*1200,desnity=2.5),导致分辨率碎片化也是比较严重,而我们的做法是以不变应万变,就是通过dp来适配各种手机屏幕。

这里解释一下dp的工作原理,
比如一台720px*1280px(desnity为2)的手机,我们除以2可以得到手机宽高为360dpi*640dpi,而1080px*1920px(desnity为3)的手机,我们除以三得到手机宽高也是为360dpi*640dpi,通过这种方式,我们不需要关心手机的实际像素,只关注dpi即可,我们在布局中只要保证宽高都用dp来表示,最宽为360dpi,最高为640dpi,在这个基础上布局,就可以无视屏幕实际的像素。这样我们写的30dp,在720P手机会显示成60px,在1080P的手机上则会显示成90px。
而我们的图片资源也要对应放入drawable-hdpi/drawable-xhdpi/drawable-xxhdpi/drawable-xxxhdpi中。系统会自动找到对应的目录去显示,如果找不到则找临近的目录进行缩放处理

这里有两点需要注意:
1、早期的手机,也就是我们说的小屏手机480px*800px手机的dpi宽高为320dpi*533dpi,320px*480px为320dpi*480dpi, 240px*320px为320dpi*427dpi。
可以看到,这些手机的宽度都是320dpi,比后来的手机360dpi要小,也就是说如果写死布局360dp,在小屏手机横向是展示不全的。而这三种手机的竖向又各不相同,所以我们在竖向布局也不可以写死高度。
好在这些都是Android早期的设计上的问题,现在的手机都是严格按照360dpi*640dpi,这也减少了我们布局的适配难度。
2、Pad的适配,我们以上的内容都是基于手机来讲的,在pad上,简单来说就是把同样的分辨率分到更大的面积,这必然导致屏幕密度的减少,比如720*1280,5英寸的手机,desnity为2,如果是10英寸的pad,desnity就变成了1。



四、具体适配技巧
1、布局尽量使用相对布局,外层如需铺满则写match_parent,不要直接写死像素
2、对于小屏手机,尤其要注意是不是会有展示不全或者重叠展示的问题。
3、一套资源无法实现完美适配的情况下,可以考虑为小屏单出图,单写布局或者在demis中为小屏手机写死布局的宽高来适配。
drawable、layout、values都是支持在文件夹后面接-hdpi这种写法来为不同dpi来适配的。
4、横竖屏的适配:Android支持drawable-port-hdpi、drawable-land-hdpi的方式来适配横竖屏不同的布局。
5、pad的适配:Android中认为屏幕的寨边大于600dpi则认为是pad,比如720px*1280px,10英寸的pad,desnity为1,所以dpi宽高为720dpi*1280dpi,这时就认为当前是pad,
如果需要为这种pad屏幕适配,可以写成drawable-sw600dp,即标识屏幕最短边大于600dpi时使用这个文件夹下的资源。
res/layout-sw600dp/main_activity.xml   # For 7” tablets (600dp wide and bigger)
res/layout-sw720dp/main_activity.xml   # For 10” tablets (720dp wide and bigger)

参考资料:
http://developer.android.com/guide/practices/screens_support.html
http://jingyan.baidu.com/article/5553fa820487f865a23934e3.html
http://www.cnblogs.com/zealotrouge/archive/2012/11/23/2784774.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值